오픈채팅방

eunheelog·2023년 6월 3일
0

programmers

목록 보기
4/15

프로그래머스 - 오픈채팅방

문제 요약


  • 채팅방에 들어오면 "[닉네임]님이 들어왔습니다."
  • 채팅방에서 나가면 "[닉네임]님이 나갔습니다."
  • 채팅방에서 닉네임 변경하는 방법
    ① 채팅방을 나간 후, 새로운 닉네임으로 다시 들어간다.
    ② 채팅방에서 닉네임을 변경한다.
  • 닉네임 변경 시 기존의 메시지들의 닉네임도 전부 변경 !

record 설명


  • 모든 유저는 [유저 아이디]로 구분
  • 채팅방 입장 시 "Enter [유저 아이디][닉네임]"
  • 채팅방 퇴장 시 "Leave [유저 아이디]
  • 닉네임 변경 시 "Change [유저 아이디][닉네임]"

💡 Idea

  1. 채팅방 입/퇴장 기록을 어떻게 저장할까?
    1) 채팅방 입/퇴장 종류, 유저 아이디, 닉네임 세가지를 다 저장하자 !
    → 세가지를 전부 저장하려면 tuple을 써야하고 복잡해지는데 다른 방법 없을까?
    2) 채팅방 입/퇴장 종류, 유저 아이디만 queue에 저장하고 유저아이디로 닉네임을 찾으면 되지 않을까?
    → 입/퇴장 종류, 유저 아이디를 저장하는 queue, 유저아이디와 닉네임을 저장하는 map 생성 !

  2. 기록들을 어떻게 저장하고 닉네임을 어떻게 변경할까?
    → Change일 경우에는 queue에 push할 필요가 없고, Leave일 경우에는 닉네임을 변경할 필요가 없다.
    (즉, Change 외에는 queue에 저장, Leave 외에는 닉네임 변경)

Source Code

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

#define type 0
#define id 1
#define name 2

using namespace std;

vector<string> solution(vector<string> record) {
    vector<string> answer;
    map <string, string> map;
    queue <pair<string, string>> list;
   
    for(int i=0; i<record.size(); i++) {
        int idx = 0;
        string input[3], tmp;
        stringstream ss(record[i]);
        while(ss >> tmp) {
            input[idx++] = tmp;
        }
       
        if(map.find(input[id]) == map.end()) { // 존재하지 않는 유저
            map.insert(make_pair(input[id], input[name]));
        }
       
        if(input[type] != "Leave") { // 나가는 경우 외에
            map[input[id]] = input[name]; // 닉네임 변경
        }
       
        if(input[type] != "Change") {
            list.push(make_pair(input[type], input[id]));
        }
    }
   
    while(!list.empty()) {
        pair<string, string> now = list.front();
        list.pop();
        string result = map[now.second] + "님이 ";
        if(now.first == "Enter") {
            result += "들어왔습니다.";
        }
        else result += "나갔습니다.";
        answer.push_back(result);
    }
   
    return answer;
}

Feedback


  1. record가 공백으로 분리되어있는데 공백의 위치를 찾아 자르려고 하니 복잡했음.
    → 다른 방법을 찾다가 sstream 발견 !

Remind


  • sstream을 사용해 공백 기준으로 분리하는 방법 (while로 배열에 저장)
      #include <sstream>
      stringstream ss(str); // str : 분리할 문자열
      int idx = 0;
      while(ss >> tmp) { // tmp : str에서 공백 기준으로 자른 문자열
          input[idx++] = tmp;
      }
  • while 쓰지 않고 여러 변수에 저장할 수도 있음.
      #include <sstream>
      string a, b, c;
      stringstream ss(str); // str : 분리할 문자열
      ss >> a >> b >> c;
profile
⛧1일 1알고리즘⛧

0개의 댓글