알고리즘/프로그래머스

2019 KAKAO BLIND RECRUITMENT - 오픈채팅방

모든 문제는 C++로 구현되어 있습니다.

 

이 문제는 유저 아이디와 닉네임을 맵으로 매핑시키고, record 배열의 첫 번째 단어가 Enter인지, Leave인지, Change인지 확인하여 그에 맞는 처리를 해주면 풀 수 있다.

 

record 배열의 원소를 단어별로 나눠주는 작업을 처리하기 위해 고민을 좀 했는데, stringstream을 사용하여 쉽게 문자열을 분리할 수 있는 방법이 있어 그 방법을 사용했다.

//출처 : https://psychoria.tistory.com/666

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

//첫번째 방법 : std::getline 이용, 구분자를 마음대로 설정할 수 있음.
vector<string> tokenize_getline(const string& data, const char delimiter = ' ') {
	vector<string> result;
	string token;
	stringstream ss(data);

	while (getline(ss, token, delimiter)) {
		result.push_back(token);
	}
	return result;
}

// 두번째 방법 : >> 연산자 사용, 구분자가 공백이나, 개행문자로 제한됨.
vector<string> tokenize_operator(const string& data) {
	vector<string> result;
	string token;
	stringstream ss(data);

	while (ss >> token) {
		result.push_back(token);
	}
	return result;
}

이 문제는 구분자가 공백으로만 되어있어서 좀 더 간단한 두 번째 방법을 사용하기로 했다. 단어별로 나눠주는 작업이 끝나면 첫 번째 단어가 무엇인지(Enter, Leave, Change)에 따라 처리를 해주면 된다.

처리한 값은 vector<pair<int, string>> 형의 변수 log에 저장해준다.

 

1. Enter - 맵에서 유저 아이디를 찾아 닉네임을 바꿔주고, 배열 log에 <0, 유저 아이디>의 형태로 값을 추가해준다.

2. Leave - 배열 log에 <1, 유저 아이디>의 형태로 값을 추가해준다.

3. Change - 맵에서 유저 아이디를 찾아 닉네임을 바꿔준다.

 

작업이 모두 끝나면 log 배열을 순회하며 원소의 두 번째 값을 맵에 넣어 최종 닉네임을 찾고, 원소의 첫 번째 값이 0이면 들어왔습니다, 1이면 나갔습니다로 하여 최종 result 배열에 차례대로 넣어주면 된다.

 

#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <unordered_map>
using namespace std;

vector<string> solution(vector<string> record) {
    vector<string> answer;
    vector<pair<int, string>> log;
    unordered_map<string, string> mappingInfo;
    
    for(auto str : record){
        vector<string> tokenList;
        string token;
        stringstream ss(str);
        
        while(ss>>token){
            tokenList.push_back(token);
        }

        switch(tokenList[0][0]){
            case 'E': //enter
                mappingInfo[tokenList[1]]=tokenList[2];
                log.emplace_back(0, tokenList[1]);
                break;
            case 'L': //leave
                log.emplace_back(1, tokenList[1]);
                break;
                
            case 'C': //change
                mappingInfo[tokenList[1]]=tokenList[2];
                break;
        }
    }
    
    for(auto it : log){
        string nick=mappingInfo[it.second];
        if(it.first==0){ //enter
            answer.push_back(nick+"님이 들어왔습니다.");
        }
        else{//leave
            answer.push_back(nick+"님이 나갔습니다.");
        }
    }
    return answer;
}