프로그래머스 - 브라이언의 고민 (실패)

well-life-gm·2021년 11월 26일
0

프로그래머스

목록 보기
65/125

프로그래머스 - 브라이언의 고민

개인적으로 문제 신뢰도에 굉장히 의문이 든다.. ㅠㅠ

정답자 코드를 보면 테스트 케이스를 모두 커버못해도 정답인 코드가 많다;
심지어 내 코드는 그 케이스를 모두 커버하는데도 정답이 아니라고 나온다...

사용한 테스트 케이스는 아래와 같다...

"HaEaLaLaObWORLDb" => "HELLO WORLD"
"SpIpGpOpNpGJqOqA" => "SIGONG JOA"
"AxAxAxAoBoBoB" => "invalid"
"HaEaLaLaObWORLDb" => "HELLO WORLD"
"SpIpGpOpNpGJqOqA" => "SIGONG JOA"
"AxAxAxAoBoBoB" => "invalid"
"aIaAM" => "I AM"
"AAAaBaAbBBBBbCcBdBdBdBcCeBfBeGgGGjGjGRvRvRvRvRvR" => "AAA B A BBBB C BBBB C BB GG GGG RRRRRR"
"aaA" => "invalid"
"Aaa" => "invalid"
"HaEaLaLaOWaOaRaLaD" => "invalid"
"aHELLOWORLDa" => "HELLOWORLD"
"HaEaLaLObWORLDb" => "HELL O WORLD"
"HaEaLaLaObWORLDb" => "HELLO WORLD"
"aHbEbLbLbOacWdOdRdLdDc" => "HELLO WORLD"
"abAba" => "invalid"
"HELLO WORLD" => "invalid"
"xAaAbAaAx" => "invalid"
"AbAaAbAaCa" => "invalid"
"AbAaAbAaC" => "invalid"
"aCaCa" => "invalid"
"aGbWbFbDakGnWnLk" => "GWFD GWL"
"a" => "invalid"
"HaEaLaLaObWORLDbSpIpGpOpNpGJqOqAdGcWcFcDdeGfWfLeoBBoAAAAxAxAxAA" => "HELLO WORLD SIGONG JOA GWFD GWL BB AAA AAAA A"
"aBcAadDeEdvAvlElmEEEEm" => "BA DE A E EEEE"
"AaABCDEBbB" => "AA BCDE BB"
"aAAAAAAa" => "AAAAAA"
"aAAAAAAabBBBBBb" => "AAAAAA BBBBB"
"AaA" => "AA"
"" => "invalid"
"aa" => "invalid"
"A" => "A"
"AB" => "AB"
"aHbEbLbLbOacWdOdRdLdDc" => "HELLO WORLD"
"aAAAAAbAAAAa" => "invalid"
"AaAA" => "AA A"
"aaaA" => "invalid"
"AaAaAa" => "invalid"
"AaAAa" => "A AA"
"bAaAb" => "AA"
"bAaAcAb" => "invalid"
"bAaAcAaBb" => "invalid"
"AaAaBBB" => "AAB BB"
"TxTxTxbAb" => "invalid"
"bTxTxTaTxTbkABaCDk" => "invalid"
"aAa" => "A"
"xAaAbAaAx" => "invalid"
"aHELLOaAbWORLDb" => "HELLO A WORLD"

코드는 아래와 같다... 반례 찾아주시면,,

#include <string>

using namespace std;

// 전역 변수를 정의할 경우 함수 내에 초기화 코드를 꼭 작성해주세요.
string solution(string sentence) {
    if(sentence.size() == 0)
        return "invalid";
    
    string answer = "";
    int ad[32]; 
    for(int i=0;i<32;i++) 
        ad[i] = 0;
    
    for(auto it : sentence) {
        if(islower(it))
            ad[it - 'a']++;
        // sentence에 공백이 포함되어 있으면 invalid
        if(isspace(it))
            return "invalid";
    }
    
    for(int i=0;i<sentence.size();i++) {
        // Case 2으로 시작
        if(islower(sentence[i])) {
            // 이미 다 사용된 소문자라면 invalid
            if(ad[sentence[i] - 'a'] == 0)
                return "invalid";
            ad[sentence[i] - 'a']--;
            
            // 소문자 두개가 연속으로 나오는 경우 invalid
            if(i + 1 < sentence.size() && islower(sentence[i + 1]))
                return "invalid";
            
            bool contain_case1 = false;
            char base_char;
            // Case2 안에 Case 1이 포함되어 있는 경우
            if(i + 2 < sentence.size() && islower(sentence[i + 2]) && sentence[i] != sentence[i + 2]) {
                contain_case1 = true;
                base_char = sentence[i + 2];
            }

            int base = i;
            int idx = 1;
            // sentence[i]와 같은 소문자가 나올때까지 실행
            while(1) {
                if(base + idx > sentence.size() - 1)
                    return "invalid";
                
                // 조건에 만족하면 stop, 이 후 다시 등장하면 안되기 때문에 남은 갯수 0으로 설정
                if(sentence[base + idx] == sentence[i]) {
                    ad[sentence[base + idx] - 'a'] = 0;
                    if(contain_case1)
                        ad[base_char - 'a'] = 0;    
                    break;
                }
                
                if(contain_case1) {
                    // 대문자는 결과 값에 포함시킴
                    if(isupper(sentence[base + idx]))
                        answer += sentence[base + idx];                        
                    else {
                        // 이미 사용된 소문자가 포함되어 있는 경우
                        if(ad[sentence[base + idx] - 'a'] == 0)
                            return "invalid";
                        ad[sentence[base + idx] - 'a']--;
                        
                        // 만약 첫 소문자와 다른 소문자라면 invalid
                        if(base_char != sentence[base + idx])
                            return "invalid";
                    }
                } else {
                    // 순수 Case2인데, 소문자를 포함하고 있고, 그것이 sentence[i]와 다르다면 invalid
                    if(islower(sentence[base + idx]) && sentence[base + idx] != sentence[i])
                        return "invalid";
                    answer += sentence[base + idx];  
                }
                
                idx++;
            }
            i = base + idx;
            if(i != sentence.size() - 1)
                answer += ' ';
            continue;
        } 
        // Case 1 혹은 순수 대문자
        if(isupper(sentence[i])) {
            bool is_case1 = false;
            // 대문자 바로 다음이 소문자일 때, 해당 소문자의 다음 소문자 까지의 거리를 구함
            if(i + 1 < sentence.size() && islower(sentence[i + 1])) {
                if(ad[sentence[i + 1] - 'a'] == 0)
                    return "invalid";
                // 만약 해당 소문자가 1개만 존재한다면 무조건 Case1
                if(ad[sentence[i + 1] - 'a'] == 1)
                    is_case1 = true;
                else {
                    int base_char = sentence[i + 1];
                    int j;
                    for(j=i+2; j<sentence.size(); j++) 
                        if(sentence[j] == base_char) 
                            break;

                    int distance = j - (i + 1);
                    // 소문자가 붙어있는 경우 invalid
                    if(distance < 2)
                        return "invalid";
                    // 만약 거리가 2이면서, sentence의 마지막이 아니라면 case1
                    if(distance == 2 && j != sentence.size() - 1)
                        is_case1 = true;   
                }
            }
             
            // 순수 대문자일 경우
            if(!is_case1) {
                int base = i;
                int idx = 0;
                int end_point = i;
                while(1) {
                    if(base + idx > sentence.size() - 1) {
                        end_point = base + idx - 1;
                        break;
                    }
                    
                    // 소문자를 만나면 어디까지 추가할지 정한 뒤 stop
                    if(islower(sentence[base + idx])) {
                        if(base + idx + 2 == sentence.size()) {
                            if(base != 0) {
                                // ABCD AbA
                                answer.pop_back();
                                end_point = base + idx - 2;
                                break;
                            } else {
                                // AbA
                                ad[sentence[base + idx] - 'a'] = 0;
                                answer += sentence[base + idx + 1];
                                end_point = base + idx + 1;
                                break;
                            }
                        }
                        if(islower(sentence[base + idx + 2])) {
                            // ABCD aAa ...
                            if(sentence[base + idx] == sentence[base + idx + 2]) {
                                // ABC DaAaBaC ... or ABC DaA
                                if(ad[sentence[base + idx] - 'a'] != 2) {
                                    answer.pop_back();
                                    end_point = base + idx - 2;
                                    break;
                                } else {
                                    // ABCD aAa D
                                    end_point = base + idx - 1;
                                    break;    
                                }
                            } else {
                                if(ad[sentence[base + idx] - 'a'] == 1) {
                                    // AbA a ...
                                    answer += sentence[base + idx + 1];
                                    ad[sentence[base + idx] - 'a'] = 0;
                                    end_point = base + idx + 1;
                                    break;
                                } else {
                                    // A bAa ...Ab
                                    end_point = base + idx - 1;
                                    break;
                                }
                            }
                        } else {
                            // ABCD aAA ...
                            if(ad[sentence[base + idx] - 'a'] == 1) {
                                // AaA A
                                answer += sentence[base + idx + 1];
                                ad[sentence[base + idx] - 'a'] = 0;
                                end_point = base + idx + 1;
                                break;
                            } else {
                                // A aABCDa 
                                end_point = base + idx - 1;
                                break;
                            }
                        }
                    }
                    answer += sentence[base + idx];
                    idx++;
                }
                i = end_point;
                if(i != sentence.size() - 1)
                    answer += ' ';
                continue;
            } else {
                // Case1의 경우
                int base = i;
                int idx = 0;
                char base_char = sentence[base + idx + 1];
                if(ad[base_char - 'a'] == 0)
                    return "invalid";
                while(1) {
                    if(base + idx > sentence.size() - 1)
                        break;

                    // 만약 소문자일 때
                    if(islower(sentence[base + idx])) {
                        // 첫 소문자와 다른 소문자라면 break
                        if(sentence[base + idx] != base_char) {
                            idx--;
                            break;
                        }
                        // 만약 이미 사용된 소문자라면 invalid
                        if(ad[sentence[base + idx] - 'a'] == 0)
                            return "invalid";
                        ad[sentence[base + idx] - 'a']--;
                        // 소문자를 다 소모했다면 다음 대문자까지만 포함시키고 break
                        if(ad[sentence[base + idx] - 'a'] == 0) {
                            idx++;
                            // Case1인데 문장의 끝이 소문자였다는 것이므로 invalid;
                            if(base + idx > sentence.size() - 1)
                                return "invalid";
                            answer += sentence[base + idx];
                            break;
                        }
                    } else {
                        answer += sentence[base + idx];
                        // 지금 대문자인데, 다음 것도 대문자라면 break
                        if(base + idx + 1 < sentence.size() && isupper(sentence[base + idx + 1]))
                            break;
                        // 지금 대문자인데, 다음이 소문자고 그것이 base_char와 다를 때 break
                        if(base + idx + 1 < sentence.size() && islower(sentence[base + idx + 1])) {
                            if(sentence[base + idx + 1] != base_char) {
                                ad[base_char - 'a'] = 0;
                                break;
                            }
                        }
                    }
                    idx++;
                }
                // 해당 소문자가 다시 등장하면 안되기 때문에 0으로 설정
                ad[base_char - 'a'] = 0;
                i = base + idx;
                if(i != sentence.size() - 1)
                    answer += ' ';
                continue;
            }
        }
    }
    return answer;
}
profile
내가 보려고 만든 블로그

0개의 댓글