コードテスト|(c++)プログラマー:フルコースを走っていない選手


に質問


多くのマラソン選手がマラソンに参加した.1人の選手を除いて、すべての選手がマラソンを完走した.
マラソンに出場する選手の名前と完走した選手の名前の並びが完成したら、完走していない選手の名前を返す解決関数を書いてください.

制限

  • マラソンに出場する選手は1人以上10万人以下.
  • 完了長さは参加者長1より小さい.
  • 参加者の名前は20文字を超えない.
  • の参加者には同名の人がいる可能性があります.
  • 🎹📢I/O例



    例1
    「leo」は参加者名簿に載っているが、フルコースを走る者名簿には載っていないため、フルコースを完走できなかった.
    例2
    「vinko」は参加者名簿に載っていたが、完走者名簿に載っていなかったため完走できなかった.
    例#3
    「誤導」は参加者リストに2人いたが、完走者リストには1人しかいなかったため、1人は完走しなかった.

    ほどく

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm> // sort함수를 사용하기 위한 라이브러리
    #include <unordered_map> // 중복을 허용하지 않고, 정렬 없이 저장하는 공식 표준 해시맵이다.
    
    using namespace std;
    
    string solution(vector<string> participant, vector<string> completion) {
        string answer = "";
    
        // unordered_map<key type, value type>
        unordered_map<string, int> members;
    
        // key : 참가한 선수 이름, value : +1
        for (auto par : participant) members[par]++;
    
        // key : 완주한 선수 이름, value : -1
        for (auto com : completion) members[com]--;
    
        // 해시 맵을 순회하여 value값이 0인 선수를 찾아서 반환 값에 대입한다.
        for (auto member : members)
        {
            // first : key 값, second : value 값
            if (member.second > 0) {
                answer = member.first;
                break; // 완수자와 참가자의 길이는 1차이 즉, 미완주자는 한명밖에 없으므로 종료
            }
        }
    
        return answer;
    }
    
    // vector만을 이용해서 푸는 경우
    string solution(vector<string> participant, vector<string> completion, bool isVector) {
        // 빠른 비교를 위해 참가자 및 완료자 목록을 정렬해준다.
        // 같은 이름은 같은 인덱스에 배치된다.
        sort(participant.begin(), participant.end());
        sort(completion.begin(), completion.end());
    
        for (int i = 0; i < completion.size(); i++)
        {
            // 참가 선수가 완주 선수가 이름이 같은지 비교한다.
            // compare() 문자열 비교 같으면 0 아니면 -1 또는 1을 내뱉는다.
            if (participant[i].compare(completion[i]) != 0) {
                return participant[i];
            }
        }
    
        // 완주하지 못한 선수가 반드시 있으므로 비교해서 찾지 못했으면
        // 정렬된 후의 마지막 선수가 미완주 선수이다.
        return  participant[participant.size() - 1];
    }
    
    
    int main() {
        
        // unordered_map을 사용하여 푼 함수를 이용
        cout << solution({ "leo", "kiki", "eden" }, { "eden", "kiki" }) << endl;
    
        cout << solution({ "marina", "josipa", "nikola", "vinko", "filipa" }, 
            { "josipa", "filipa", "marina", "nikola" }) << endl;
    
        cout << solution({ "mislav", "stanko", "mislav", "ana" }, 
            { "stanko", "ana", "mislav" }) << endl;
    
        // vector를 응용하여 푼 함수를 이용
        cout << solution({ "leo", "kiki", "eden" }, { "eden", "kiki" }, true) << endl;
    
        cout << solution({ "marina", "josipa", "nikola", "vinko", "filipa" }, 
            { "josipa", "filipa", "marina", "nikola" }, true) << endl;
    
        cout << solution({ "mislav", "stanko", "mislav", "ana" }, 
            { "stanko", "ana", "mislav" }, true) << endl;
    
        return 0;
    }
    最初の5分は「全部解けた~!結果を誤って提示したため、正確性テストは合格したが、効率的に失敗した.私の最初の答えは、参加者リストとフルコースを走る者リストを二重の複文で比較し、リストから削除することです.だから思ったより簡単だと思いますが、このように解けたわけではありません!彼は知っているだけ見られると言って、他の方法を考えたことがない.私はただ既存の限られた状態で応用したいだけです!!失敗したコードを見てみましょう.

    正確性テストに合格したものの、効率面では合格しなかったコード

    string solution(vector<string> participant, vector<string> completion) {
        string answer = "";
    
        // 참가한 선수 목록과 완주한 선수 목록을 비교하여
        // 완주한 선수를 두 목록에서 뺀다. 그리고 완주하지 못한 선수만 남는다.
        for (int i = 0; i < participant.size();)
        {
            bool isParticipantErase = false;
            for (int k = 0; k < completion.size(); )
            {
                // 효율성을 위해 한글자만 먼저 비교
                if (participant[i][0] == completion[k][0]) {
                    // 문자열 비교 같으면 0 아니면 -1 또는 1을 내뱉는다.
                    if (participant[i].compare(completion[k]) == 0) {
                        participant.erase(participant.begin() + i);
                        completion.erase(completion.begin() + k);
                        isParticipantErase = true;
                        break;
                    }
                    else k++;
                }
                else k++;
                
            }
            if(isParticipantErase == false)
                i++;
        }
    
        answer = participant[0];
    
        return answer;
    }

    参考資料とサイト(ありがとうございます)

  • https://programmers.co.kr/learn/courses/30/lessons/42576