Programmers: 오픈채팅방

KangDroid·2021년 5월 26일
0

Algorithm

목록 보기
19/27

문제

문제 요약

  • 오픈채팅방에서 변경되는 닉네임을 잘 추적하고,
  • 최종적으로 오픈채팅방에 출력되는 스트링을 구하면 됨!
  • 최종적으로 오픈채팅방에 남는 스트링은
    • '최종' 닉네임을 반영한다.

핵심

  • State는 총 Enter, Leave, Change 이 세가지가 있음
    • 근데 닉네임 관점에서 따져보면, Leave는 그리 중요치 않음
    • 왜냐, Leave단계에서는 유저 아이디가 바뀌지 않음
    • 추가적으로 잘못된 입력은 주어지지 않는다이다!
  • UID는 바뀌지 않으니까, 이걸 중심으로 Nickname을 추적하면 끝!
    • HashMap[Unordered Map]
    • Key = UID, Value = Nickname

알고리즘

입력 배열 = record

  • 입력 배열을 쭉 돌면서, Nickname을 업데이트 한다
    • 각 Record의 State가 Leave가 아닌 경우, 닉네임을 업데이트함
      • 유저 맵 변수에 'UID'가 있는 경우 Record 기준으로 Nickname을 업데이트
      • 유저 맵 변수에 'UID'가 없는 경우 새로 Record 기준으로 Nickname을 업데이트
      • -> 즉, Record에 있는 Nickname으로 모두 업데이트
    • 이 함수를 실행하면, 유저 맵에는 최종 UID와 그에 매칭되는 NickName이 생성된다.
  • 입력 배열을 쭉 돌면서, Result 스트링을 생성한다.
    • UID 구분만 잘 하고, UID에 해당하는 NickName을 맵에서 가져와서 스트링을 생성한다.

코드

#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;

#define STATE 0
#define UID_VALUE 1
#define NICKNAME 2

#define ENTER_STATE "Enter"
#define LEAVE_STATE "Leave"
#define CHANGE_STATE "Change"

// Map, Key: UID, Value: NickName
unordered_map<string, string> username_map;

void print_map() {
    for (auto i = username_map.begin(); i != username_map.end(); i++) {
        cout << i->first << " " << i->second << endl;
    }
}

vector<string> parse_each_record(string record) {
    vector<string> parsed;
    string tmp = "";
    for (int i = 0; i < record.length(); i++) {
        if (record[i] != ' ') {
            tmp += record[i];
        } else {
            parsed.push_back(tmp);
            tmp = "";
        }
    }

    if (tmp != "") {
        parsed.push_back(tmp);
    }
    return parsed;
}

void update_each_record(string record) {
    vector<string> parsed = parse_each_record(record);
    if (parsed[STATE] != LEAVE_STATE) {
        // Case 1. Initial Enter
        if (username_map.find(parsed[UID_VALUE]) == username_map.end()) {
            // Add
            username_map.insert(make_pair(parsed[UID_VALUE], parsed[NICKNAME]));  
        } else {
            // Case 2. Already OUT -> and re-enter[Nickname Change]
            username_map[parsed[UID_VALUE]] = parsed[NICKNAME];
        }
    }
}

vector<string> solution(vector<string> record) {
    vector<string> answer;
    // Update Record
    for (string each_record : record) {
        update_each_record(each_record);
    }

    // Print out
    for (string each_record : record) {
        vector<string> parsed = parse_each_record(each_record);
        if (parsed[STATE] == ENTER_STATE) {
            answer.push_back(username_map[parsed[UID_VALUE]] + "님이 들어왔습니다.");
        } else if (parsed[STATE] == LEAVE_STATE) {
            answer.push_back(username_map[parsed[UID_VALUE]] + "님이 나갔습니다.");
        }
    }
    return answer;
}
profile
Student Platform[Backend] Developer

0개의 댓글