문제 풀이/Programmers 문제 풀이

[Programmers 알고리즘, C++]#Level2_오픈 채팅방

Hardii2 2022. 8. 14. 20:50

[Programmers 알고리즘, C++]#Level 2_오픈 채팅방

 

Programmers 알고리즘 문제 풀이, Level2_오픈 채팅방

STL 컨테이너와 String 클래스를 활용하여 풀이하는 문제입니다.

 


 

문제

 

 

풀이

 

1. [유저 아이디] + [닉네임] 을 묶어서 기억하기 위해 STL 컨테이너 중 "map"을 활용합니다.

 

[Basic C++] #38_map, 연관 컨테이너

[Basic C++] #38_map, 연관 컨테이너 C++ 개발에서 표준 라이브러리(STL)의 "map"에 대해 알아보겠습니다. "전문가를 위한 C"의 16 항목, "컨테이너와 반복자 이해하기"에 해당하는 내용입니다. map, 연관 컨

webddevys.tistory.com

 

2. 주요 포인트는 닉네임이 변경되는 시점은 두 가지입니다. "Enter"와 "Change"입니다.

3. "Enter", 입장의 경우 이전 닉네임을 유지할 수도, 새로운 닉네임으로 변경할 수도 있습니다.

4. STL 알고리즘 중 "find"를 활용하여 [유저 아이디]를 Key로 마지막으로 업데이트한 [닉네임]과 같은지 확인

5. 새로운 [유저 아이디]라면, STL 알고리즘 중 "insert"를 활용하여 [유저 아이디] + [닉네임]을 삽입합니다.

5. "Change", 변경의 경우 확정적으로 새로운 닉네임으로 변경합니다.

6. "operator []"를 활용하여 기존에 저장된 [유저 아이디]를 활용하여 새로운 닉네임을 대입합니다.

 

코드
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <utility>

using namespace std;

// 1. key = [유저 아이디], value = [닉네임]
map<string, string> changeRecord;

// 2. bool = 입장 or 퇴장, string = [유저 아이디]
vector<pair<bool, string>> resultRecord;

vector<string> solution(vector<string> record)
{
    vector<string> answer;

    string Enter = "님이 들어왔습니다.";
    string Leave = "님이 나갔습니다.";

    for (int i = 0; i < record.size(); ++i)
    {
        bool bDelimFound = false;
        string userString = "";
        string nickString = "";

        // "Enter"
        if (record[i].substr(0, 5) == "Enter")
        {
            for (int j = 6; j < record[i].size(); ++j)
            {
                if (bDelimFound == false && record[i][j] == ' ')
                {
                    bDelimFound = true;
                    continue;
                }

                if (bDelimFound != true)
                    userString += record[i][j];
                else
                    nickString += record[i][j];
            }
            // [유저] [닉네임]
            // 1. find : 이미 존재하는 [유저 아이디] 확인
            if (changeRecord.find(userString) != end(changeRecord))
            {
                changeRecord[userString] = nickString;
            }
            // 2. insert : 새로운 [유저 아이디] + [닉네임]을 pair로
            else
            {
                changeRecord.insert(make_pair(userString, nickString));
            }
            resultRecord.push_back(make_pair(true, userString));
        }
        // "Leave"
        else if (record[i].substr(0, 5) == "Leave")
        {
            for (int j = 6; j < record[i].size(); ++j)
            {
                userString += record[i][j];
            }

            resultRecord.push_back(make_pair(false, userString));
        }
        // "Change"
        else
        {
            for (int j = 7; j < record[i].size(); ++j)
            {
                // " "를 만나면 Flag 변수를 True로 변경합니다.
                if (bDelimFound == false && record[i][j] == ' ')
                {
                    bDelimFound = true;
                    continue;
                }

                // " " 직전까지 [유저 아이디] + " " 이후부터 [변경 닉네임]
                if (bDelimFound != true)
                    userString += record[i][j];
                else
                    nickString += record[i][j];
            }
            // 3. operator [] : 기존의 [유저 아이디]를 kEY로 새로운 [닉네임]을 삽입합니다.
            changeRecord[userString] = nickString;
        }
    }

    for (int i = 0; i < resultRecord.size(); i++)
    {
        // 1. resultRecord에 존재하는 [유저 아이디]를 Key로 changeRecord에서 [최종 닉네임]을 찾습니다.
        string userID = resultRecord[i].second;
        string resultStr = changeRecord[userID];
        // 2. 입장
        if (resultRecord[i].first == true)
            resultStr.append(Enter);
        // 3. 퇴장
        else
            resultStr.append(Leave);

        answer.push_back(resultStr);
    }

    return answer;
}