개인적으로 문제 신뢰도에 굉장히 의문이 든다.. ㅠㅠ
정답자 코드를 보면 테스트 케이스를 모두 커버못해도 정답인 코드가 많다;
심지어 내 코드는 그 케이스를 모두 커버하는데도 정답이 아니라고 나온다...
사용한 테스트 케이스는 아래와 같다...
"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;
}