[プログラマー]オープンチャットルーム(C++)


ワークフローアルゴリズム学習28週間kakao出力


オープンチャットルーム|質問ショートカット

回答(2022年3月22日TUE)💻)


解の核心


文字列の分割処理さえすれば、何の困難もありません.
△実は、文字列に触れると頭が真っ白になる国です...文字列の問題と親しくなるために選んだ問題です.
C++にはsplit関数がなく,適切な対策が必要である.
最初はfindとsubstrを用いて解くが,コードは少し複雑である.
もう一つの方法はStringstreamです
🚨 実際,substr(pos,count)は[pos,count)範囲を返す文字列と勘違いしていたので,...[pos,pos+count]が正しい戻り範囲であることをいくつか挿入した.
でも特に(?)
コードには毒性はありませんがstringstreamよりも効率的にfind&substrを体現しています
stringstreamはcopyがあるからかもしれません

find&substを使用した場合の結果



stringstreamを使用した場合の結果



findとsubstrおよびgetline
👉 [C++]有用なライブラリと関数-#は<string>部分を含むこの記事を参考にすればOK

リファレンスstringstream

  • 文字列用ストリーム
  • 主に所与の文字列に必要な情報をデータ型別にグループ化して抽出するためのもの
  • #include <sstream>必要
  • スペースと改行しない文字列から適切なデータ型を抽出
  • // example #1
    string original = "Hello World!";
    stringstream ss(original);
    char ch;
    while (ss >> ch) {
        cout << ch << " "; // H e l l o W o r l d !
    }
    string temp;
    while (ss >> temp) {
        cout << temp << endl;
    }
    // example #2
    stringstream ss;
    ss.str(original);
    string str;
    while (ss >> str) {
        cout << str << endl;
        // Hello
        // World!
    }

    🔽 find&substr使用コード(C++)

    #include <string>
    #include <vector>
    #include <unordered_map>
    
    using namespace std;
    
    // Solution #1) find & substr 활용
    vector<string> solution(vector<string> record) {
        vector<string> answer;
    
        int N = record.size();
        vector<string> actionVec;
        vector<string> uidVec;
        unordered_map<string, string> uidMap;
    
        for (int i=0; i<N; i++) {
            int firstDelim = record[i].find(' ');
            string action = record[i].substr(0, firstDelim);
            actionVec.push_back(action);
    
            string uid;
            if (action == "Leave") {
                uid = record[i].substr(firstDelim+1);
            }
            else {
                int secondDelim = record[i].find(' ', firstDelim+1);
                uid = record[i].substr(firstDelim+1, secondDelim-firstDelim-1);
                string nickname = record[i].substr(secondDelim+1);
                uidMap[uid] = nickname;
            }
            uidVec.push_back(uid);
        }
    
        for (int i=0; i<N; i++) {
            string result = "";
            result += uidMap[uidVec[i]];
            if (actionVec[i] == "Enter") { result +=  "님이 들어왔습니다."; }
            else if (actionVec[i] == "Leave") { result += "님이 나갔습니다."; }
            else if (actionVec[i] == "Change") { continue; }
            answer.push_back(result);
        }
        
        return answer;
    }

    Stringstream使用コード(C++)

    #include <string>
    #include <vector>
    #include <unordered_map>
    #include <sstream>
    
    using namespace std;
    
    // Solution #2) stringstream 활용
    /*
    split 함수도 만들어 보았으나
    이 문제는 delimiter가 공백이므로
    getline 없이 stringstream 만으로도 풀 수 있다
    
    vector<string> split(string str, char delim) {
        vector<string> answer;
        stringstream ss(str);
        string temp;
    
        while (getline(ss, temp, delim)) {
            answer.push_back(temp);
        }
    
        return answer;
    }
    */
    
    vector<string> solution(vector<string> record) {
        vector<string> answer;
    
        vector<pair<string, string>> actionIdVec; // {action, uid}
        unordered_map<string, string> uidNameMap; // {uid: name}
        int N = record.size();
        for (int i=0; i<N; i++) {
            // vector<string> splitVec = split(record[i], ' ');
            vector<string> splitVec;
            stringstream ss(record[i]);
            string temp;
            while (ss >> temp) {
                splitVec.push_back(temp);
            }
            actionIdVec.push_back({splitVec[0], splitVec[1]});           
            if (splitVec[0] != "Leave") {
                uidNameMap[splitVec[1]] = splitVec[2];
            }
        }
    
        for (int i=0; i<N; i++) {
            string result = "";
            result += uidNameMap[actionIdVec[i].second];
            if (actionIdVec[i].first == "Enter") { result +=  "님이 들어왔습니다."; }
            else if (actionIdVec[i].first == "Leave") { result += "님이 나갔습니다."; }
            else if (actionIdVec[i].first == "Change") { continue; }
            answer.push_back(result);
        }
        
        return answer;
    }