티스토리 뷰

반응형

오픈채팅방에서 사람들의 출입 로그를 출력하는 문제

 


문제의 조건

 

1. 한 오픈채팅방의 출입 로그가 담긴 string 배열 record가 주어지는데

각 원소는 위와 같은 규칙으로 정해져서 담겨있다. 

 

 

2. 만약 한 사람이 닉네임을 바꾸면 그 전에 출력되었던 메시지들의 닉네임도 모두 바뀐다. 

그 사람이 나갔다가 다시 들어오면서 아이디를 바꿔서 들어와도 그 전에 출력되었던 닉네임도 모두 바뀐다. 

 

=> record 배열을 처음부터 순회하면서 해시 맵에 유저아이디와 닉네임을 저장한다. 

key: 유저아이디

value: 닉네임

이렇게 저장하고 출입 로그의 첫 단어가 Enter 이거나 Change이면 key 유저아이디로 찾은 value값을 바꿔주면 된다. 

record 배열이 끝날 때엔 가장 마지막으로 사용한 닉네임으로 갱신되어 있을 것이다. 

그러면 어떤 유저가 마지막으로 사용한 닉네임을 알 수 있다. 

 

3. answer 배열에 담겨야 할 string은

~님이 들어왔습니다.

~님이 나갔습니다.

두 가지 뿐이다. 

 

=> record 배열을 순회하면서 출입 로그의 첫 단어가 Enter 이거나 Leave 이면 

임시 벡터에 [유저아이디, 들어왔습니다.(혹은 나갔습니다.)] 형태로 저장한다. 

즉 유저들의 행동을 저장할 2차원 벡터를 하나 만든다. 

 

2, 3번 과정을 거쳐서 걸러진 닉네임과 유저들의 행동 로그를 잘 합쳐서 answer 배열에 담아 리턴하면 된다. 

 


하지만 여기에 함정이 있었는데... 

 

if ("Change" != log[0])
{
    userIdAndAction.push_back(vector<string>(2));
    userIdAndAction[i][0] = log[1];
    if ("Enter" == log[0])
        userIdAndAction[i][1] = "들어왔습니다.";
    else
        userIdAndAction[i][1] = "나갔습니다.";
}

 

처음엔 2차원 벡터에 새 공간을 할당할 때 이렇게 썼었는데 

프로그래머스의 c++ 컴파일러가 엑스코드의 컴파일러와 좀 다른지 저런 방식으로 2차원 벡터에 메모리를 할당하는 코드가 프로그래머스에선 먹히지 않았다...

그래서 예제는 통과하는데 본 테스트로 넘어가면 세그폴트가 나면서 하나도 실행이 되지 않았음 ㅠ.ㅠ 

하지만 엑스코드에선 잘 되서 뭐가 문젠지 찾느라 한참 헤멨었다 ㅠㅠㅠ

 

로직은 금방 짰지만 저거 알아내느라 두 시간 헤멘 문제 ㅠ.ㅠ

아래와 같이 최종 수정하고나서 모든 테스트 케이스가 통과되었다. 

 

#include <string>
#include <vector>
#include <map>
#include <sstream>

using namespace std;

vector<string> solution(vector<string> record) {
    vector<string> answer;
    vector<vector<string>> userIdAndAction;
    map<string, string> userMap;
    for (int i = 0; record.size() > i; i++)
    {
        //처음부터 순회하면서 유저아이디와 닉네임을 맵에 저장한다.
        //만약 존재하는 유저아이디라면 나중에 바뀐 닉네임으로 교체
        stringstream ss(record[i]);
        string tmp;
        vector<string> log;
        while (ss>>tmp)
            log.push_back(tmp);

        if ("Change" != log[0])
        {
            vector<string> v;
            v.push_back(log[1]);
            if ("Enter" == log[0])
                v.push_back("들어왔습니다.");
            else
                v.push_back("나갔습니다.");

            userIdAndAction.push_back(v);
        }

        if ("Leave" != log[0])
            userMap[log[1]] = log[2];
    }

    for (int i = 0; userIdAndAction.size() > i; i++)
    {
        auto it = userMap.find(userIdAndAction[i][0]);
        string finalLog = it->second + "님이 " + userIdAndAction[i][1];
        answer.push_back(finalLog);
    }

    return answer;
}

 

이 문제를 풀며 느낀 것은 컨테이너를 쓸 때엔 어지간하면 좀 정석대로 코드를 쓰자...

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함