-
프로그래머스 Lv2 브라이언의 고민Computer Science/프로그래머스 2023. 10. 8. 16:09
첫번째로 나는 (규칙1, 규칙2, 규칙1 + 규칙2)의 조건을 검사하기로 했다.
첫번째 문자가 대문자이면 규칙1
첫번째 문자가 소문자이면 규칙2
규칙 1일 경우if (isupper(sentence[i])) { word += sentence[i]; first_rule = true; if (i + 1 == sentence.length()) { first_rule = false; words.push_back(word); word = ""; } else if (isupper(sentence[i + 1])) { first_rule = false; words.push_back(word); word = ""; } else if (islower(sentence[i + 1])) { if (checked[sentence[i + 1] - 'a']) return invalid; char_rule1 = sentence[i + 1]; vector<int> pos; for (int j = i + 1; j < sentence.length(); ++j) if (sentence[j] == char_rule1) pos.push_back(j); if (pos.size() == 1) continue; else if (pos.size() >= 3) { bool flag = true; for (int j = 1; j < pos.size(); ++j) { if (pos[i + 1] - pos[i] != 2) { flag = false; break; } } if (flag) continue; } else { first_rule = false; char_rule1 = NULL; words.push_back(word); word = ""; } } }
1. 문자열이 끝이라면 대문자 한 문자만 온 것이므로 워드안에 넣는다. 'O'
2. 다음 문자열도 대문자라면 한 문자로 끝난 것이므로 워드안에 넣는다.
3. 다음 문자가 소문자라면 다음 문자가 사용 된 소문자인지 확인하고, 검사 소문자에 넣은 후 소문자 위치를 저장한다.
3-1. 소문자가 1개이면 "OaO"이므로 다음 검사 때 대문자 한 문자만 Word에 넣고 검사 끝
3-2. 소문자가 3개 이상이면 문자의 간격이 2인지 확인한다. 문자의 간격이 2가 아니라면 flag = false로 만드는데,,
이 코드는 삭제해도 테스트 케이스를 성공했다.
if (pos.size() == 1) continue;
4. 위 코드가 이해가 안갔는데, 저장한 위치가 1개이면 ex) 0a0 꼴이므로
로 넘어가 규칙성을 검사한 후 워드에 넣는다.else if (first_rule)
규칙2의 경우
1. 사용한 검사 문자인지 확인
2. 문자가 끝났는지 확인 "a"를 생각하자.
3. 다음 문자가 소문자인지 검사한다. "aa"는 규칙에 위배되므로
위 조건에 해당하면 오류문자를 리턴한다.
if (islower(sentence[i])) { if (checked[sentence[i] - 'a']) return invalid; if (i + 1 == sentence.length()) return invalid; else if (islower(sentence[i + 1])) return invalid; second_rule = true; char_rule2 = sentence[i]; }
else if (first_rule) { if (isupper(sentence[i])) { word += sentence[i]; if (i + 1 == sentence.length()) { first_rule = false; checked[char_rule1 - 'a'] = true; char_rule1 = NULL; words.push_back(word); word = ""; } else if (isupper(sentence[i + 1])) { first_rule = false; checked[char_rule1 - 'a'] = true; char_rule1 = NULL; words.push_back(word); word = ""; } else if (char_rule1 != sentence[i + 1]) { first_rule = false; checked[char_rule1 - 'a'] = true; char_rule1 = NULL; words.push_back(word); word = ""; } } if (islower(sentence[i])) { if (i + 1 == sentence.length()) return invalid; else if (islower(sentence[i + 1])) return invalid; } }
첫번째 규칙을 검사하는 코드이다.
대문자 일 때는
1. 다음 문자가 문자열의 끝이라면 규칙1 검사를 끝낸다.
2. 다음 문자가 대문자여도 규칙1 검사를 끝낸다.
3. 다음 문자가 소문자 규칙이 아니여도 규칙1 검사를 끝낸다.
first_rule = false; // 규칙 1 OFF checked[char_rule1 - 'a'] = true; // 이제 다른 새 단어에서 이번 규칙 1 에 쓰인 소문자(특수문자)를 다신 쓸 수 없도록 체크 char_rule1 = NULL; // 리셋 words.push_back(word); // 단어 추가 word = ""; // 리셋
검사를 분기하는 변수를 끄고
검사 문자를 비워주고
해당 문자를 검사했다는것을 체크하고
word를 정답에 삽입 후 word를 비워준다.
소문자 일 때는
규칙1은 대문자로 끝나야하는데 끝나버린 것이므로
if (i + 1 == sentence.length()) return invalid;
또한 규칙1은 소문자가 연달아 올 수 없으므로
else if (islower(sentence[i + 1])) return invalid;
else if (second_rule) { if (isupper(sentence[i])) { word += sentence[i]; if (i + 1 == sentence.length()) return invalid; else if (islower(sentence[i + 1]) && char_rule2 != sentence[i + 1]) { if (char_rule2 == sentence[i - 1]) { if (checked[sentence[i + 1] - 'a']) return invalid; first_rule = true; char_rule1 = sentence[i + 1]; } else return invalid; } } if (islower(sentence[i])) { second_rule = false; checked[char_rule2 - 'a'] = true; char_rule2 = NULL; words.push_back(word); word = ""; } }
현재 대문자가 문자열의 끝인지 검사한다.
규칙2는 "aHa"꼴로 끝나야하기 때문이다.
다음 문자가 소문자인데, 규칙2 검사 문자와 다르고, 이전 문자가 규칙2 검사 문자라면
else if (islower(sentence[i + 1]) && char_rule2 != sentence[i + 1]) { if (char_rule2 == sentence[i - 1]) { if (checked[sentence[i + 1] - 'a']) return invalid; first_rule = true; char_rule1 = sentence[i + 1]; } else return invalid; }
"aHbEbLbLbOacWdOdRdLdDc"에서 "aHb"같은 부분이다.
두번째 규칙 검사 중 다음 문자가 검사2 문자가 아닌 다른 문자라면 규칙1이 적용되기 시작했다는 것이다.
마찬가지로 사용한 검사 문자열인지 확인하고 규칙1 검사가 시작했다는 것을 코드로 짜면된다.
if (islower(sentence[i])) { second_rule = false; checked[char_rule2 - 'a'] = true; char_rule2 = NULL; words.push_back(word); word = ""; }
규칙2 검사 중 다음 문자가 소문자이면 규칙2 검사를 종료하면 된다.
규칙1과 규칙2를 동시에 검사하는 코드이다.if (first_rule && second_rule) { if (isupper(sentence[i])) { word += sentence[i]; if (i + 1 == sentence.length()) return invalid; else if (isupper(sentence[i + 1])) return invalid; else if (char_rule1 != sentence[i + 1] && char_rule2 != sentence[i + 1]) return invalid; } if (islower(sentence[i])) { if (char_rule2 == sentence[i]) { first_rule = false; checked[char_rule1 - 'a'] = true; char_rule1 = NULL; second_rule = false; checked[char_rule2 - 'a'] = true; char_rule2 = NULL; words.push_back(word); word = ""; continue; } if (i + 1 == sentence.length()) return "invalid"; else if (islower(sentence[i + 1])) return "invalid"; } }
규칙1과 2를 동시 검사 중
현재 문자가 대문자인데 문자의 끝이라면 오류문자 (규칙2의 문자로 끝나야한다)if (i + 1 == sentence.length()) return invalid;
다음 문자가 대문자여도 오류문자
else if (isupper(sentence[i + 1])) return invalid;
다음 문자가 규칙1,2 문자가 아니라면 오류문자
else if (char_rule1 != sentence[i + 1] && char_rule2 != sentence[i + 1]) return invalid;
다음 문자가 소문자인데 규칙1문자이면 문자 사이사이에 껴있다는 것이므로 그냥 넘어간다.
하지만 규칙2문자이면 규칙1과 2가 끝났다는 것으로 처리하면된다.if (islower(sentence[i])) { if (char_rule2 == sentence[i]) { first_rule = false; checked[char_rule1 - 'a'] = true; char_rule1 = NULL; second_rule = false; checked[char_rule2 - 'a'] = true; char_rule2 = NULL; words.push_back(word); word = ""; continue; } }
규칙1 문자가 와서 문자가 계속 이어져야하는데, 문자열의 끝이라면 오류문자 처리한다.
또한 다음 문자가 대문자가 아닌 소문자이면 오류처리한다. 문자열 사이에 소문자가 껴있어야하므로.if (i + 1 == sentence.length()) return "invalid"; else if (islower(sentence[i + 1])) return "invalid";
'Computer Science > 프로그래머스' 카테고리의 다른 글
프로그래머스 카카오캠핑 Lv2 (1) 2023.10.09 프로그래머스 Lv 보행자 천국 (1) 2023.10.09 프로그래머스 Lv2 가장 큰 정사각형 찾기 (0) 2023.10.06 프로그래머스 Lv2 올바른 괄호 (1) 2023.10.06 프로그래머스 Lv2 다음 큰 숫 (0) 2023.10.06