본문 바로가기
coding/algorithm

[programmers] Lv.2 오픈채팅방(c++)

by 눈부신음표 2022. 4. 18.
728x90

흠.. 너무 빨리 푼거같다. 담엔 Level3를 도전해봐야겠다.(일기)

더보기
#include <bits/stdc++.h>

using namespace std;

vector<string> solution(vector<string> record) {
    vector<string> answer;
    map<string, string> id_nickname; // id 별 닉네임 관리
    queue<string> enter_leave; // enter/leave, id가 순서대로 들어감

    for(string r: record){
        istringstream iss(r);
        string op, id, nickname;
        iss >> op >> id >> nickname; // spilt

        if(op == "Enter" || op == "Change") id_nickname[id] = nickname;
        if(op == "Enter" || op == "Leave"){
            enter_leave.push(op);
            enter_leave.push(id);
        }
    }

    while(1){
        string op = enter_leave.front();
        enter_leave.pop();
        string str = (op == "Enter")? "님이 들어왔습니다." : "님이 나갔습니다.";

        string id = enter_leave.front();    
        enter_leave.pop();

        answer.push_back(id_nickname[id] + str);
        if(enter_leave.size() == 0) break;
    }
    return answer;
}

문제 정리:

https://programmers.co.kr/learn/courses/30/lessons/42888

 

코딩테스트 연습 - 오픈채팅방

오픈채팅방 카카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다. 신입사원인 김크루는 카카오톡 오

programmers.co.kr

input

  • vector<string> record : "[Enter/Leave/Change] [id] [nickname](Leave의 경우엔 없음)"

output

  • "ㅇㅇ님이 들어왔습니다." "ㅇㅇ님이 나갔습니다." 의 vecter<string> 집합

- 닉네임이 변경됐으면 이전의 닉네임들도 전부 바껴야한다.

제한사항

- 모든 유저는 id로 구분

- record안의 문자열 길이는 1 이상 10만 이하

- 유저 아이디와 닉네임 길이는 1 이상 10 이하

- 닉네임 중복 허용

728x90

[접근1]

record 안의 문자열을 쪼개자.

op 안에 Enter/Leave/Change를 넣어주고 id에 id를 nickname에 nickname을 넣어준다.(Change의 경우 공백임)

for(string r: record){
    istringstream iss(r);
    string op, id, nickname;
    iss >> op >> id >> nickname; // spilt
}

[접근2]

id로 구분되기 때문에 닉네임이 변하는것을 하나하나 관리할 필요 없이 map id_nickname에서 id를 찾아 바로 바꿔버리면 된다.

Enter의 경우 새 id와 새 nickname이 들어올 수 있고, Change의 경우 nickname이 바뀌기 때문에 그때만 id_nickname map에 접근해서 대입해준다.

Enter과 Leave와 id를 따로 queue enter_leave에 저장해둬서 정답 출력은 나중에 한다. (Change로 닉네임이 변경될것은 다 변경된 뒤에 답을 구해야함)

map<string, string> id_nickname; // id 별 닉네임 관리
queue<string> enter_leave; // enter/leave, id가 순서대로 들어감

for(string r: record){
    istringstream iss(r);
    string op, id, nickname;
    iss >> op >> id >> nickname; // spilt

    if(op == "Enter" || op == "Change") id_nickname[id] = nickname;
    if(op == "Enter" || op == "Leave"){
        enter_leave.push(op);
        enter_leave.push(id);
    }
}

[접근3]

queue를 돌면서 queue안에 아무것도 없을때까지 다음을 반복한다.

Enter또는 Leave가 앞에 있다. 그 값을 가져오고 pop()해서 없애준다.

Enter일 경우와 Leave일 경우의 닉네임 뒤에 붙을 말을 str에 담아준다.

다시 queue앞을 참조하면 id를 알 수 있고, 값을 가져온 뒤에 pop()해서 없애준다.

id_nickname에서 id를 사용해서 nickname을 알아온뒤 str과 합쳐서 answer에 넣어준다.

queue가 비었을 때 while문을 끝내고 answer값을 return 해주면 끝!

while(1){
    string op = enter_leave.front();
    enter_leave.pop();
    string str = (op == "Enter")? "님이 들어왔습니다." : "님이 나갔습니다.";

    string id = enter_leave.front();    
    enter_leave.pop();

    answer.push_back(id_nickname[id] + str);
    if(enter_leave.size() == 0) break;
}
return answer;
728x90

댓글