알고리즘 문제 풀이 / 프로그래머스 (programmers) - 브라이언의 고민
문제 링크
https://programmers.co.kr/learn/courses/30/lessons/1830
문제 풀이
public class Brianstrouble {
String answer;
boolean checkRule1 = true;
boolean checkRule2 = true;
Map<Character, String> lowerMap;
public String solution(String sentence) {
answer = "";
lowerMap = new HashMap<>();
// 변형된 문자열은 공백 X야함. 근데 있을 경우 invalid
if(sentence.contains(" ")) invalid();
else lowerCheck(sentence);
// 재귀때문에 다른 문자 있을 수 있어 answer 조건 넣어준다.
answer = answer.contains("invalid") ? "invalid" : answer.trim();
return answer;
}
public void lowerCheck(String sentence) { // 소문자 있는지 체크
int length = sentence.length();
for(int i = 0; i < length; i++) {
char lower = sentence.charAt(i);
if(Character.isLowerCase(lower)) { // 소문자 있을 때 로직
if(lowerMap.containsKey(lower)) {//사용한 소문자인 경우 탈락
invalid();
return;
}
lowerMap.put(lower, ""); // 사용한 소문자 map 저장
// 발견된 소문자의 마지막 위치 체크
int lastIndex = sentence.lastIndexOf(lower);
if(lastIndex == i || (!checkRule2 && lastIndex - i == 2 )) {
//소문자 한 개 || rule2 적용 후 소문자 개수 2개 -> rule1
//rule2 적용 후 소문자 개수 2개 이유
// > ex) aBcBcBa 의 경우 rule2 규칙을 2번 할 순 없지만,
// aa : rule2 cc: rule1 적용 가능하게 하려고
//내 규칙은 소문자가 2개면 무조건 rule2로 가게 했기 때문에 이 경우를 넣어야함.
rule1(i-1, lastIndex+2, sentence, lower);
// rule2 다녀왔다면 이제 다시 해제 why?
// > rule1을 끝냈다는건 그 후에 소문자가 없단 뜻. 따라서 이제 뒷 단어 체크.
if(!checkRule2) checkRule2 = true;
}else {
// 소문자가 2개인지 체크 > 2개면 무조건 rule2로 가게하기 위함
String anotherStr = sentence.substring(i+1, lastIndex);
boolean anotherLower = anotherStr.contains(Character.toString(lower));
if(!anotherLower) { // 소문자 2개 -> rule2
// 소문자 앞에 문자가 있다면 아무것도 해당 안되는 단어이므로 noLower() 해준후 rule2 수행
if(i != 0) {
noLower(sentence, i);
}
rule2(i+1, lastIndex, sentence, lower);
}else { // 나머지 경우 -> rule1
rule1(i-1, lastIndex+2, sentence, lower);
// rule2 다녀왔다면 true 변환.
// why? rule1을 끝냈다는건 그 후에 소문자가 없단 뜻. 따라서 이제 뒷 단어 체크해야함.
if(!checkRule2) checkRule2 = true;
}
}
break;
}else if(i + 1 == length){ // 소문자 끝까지 없을 때
noLower(sentence, i+1);
}
}
}
public void invalid() {
answer = "invalid";
}
public void answer(String sentence) {
answer += " " + sentence;
}
public void noLower(String sentence, int lastIndex) {
if(!checkRule2) return; // 문자 중복 붙임 방지
sentence = sentence.substring(0, lastIndex);
answer(sentence);
}
public void rule1(int firstIndex, int lastIndex, String sentence, char lower) {
if(!checkRule1 || sentence.charAt(0) == lower || sentence.charAt(sentence.length()-1) == lower) { // rule1 두번째 || 첫단어 / 막단어 > 소문자 경우 invalid()
invalid();
return;
}
if(firstIndex != 0) { // 소문자 앞단어가 0 이 아닐 때 > AAaAaAaA 의 경우 -> A AAAA 여야 하기 때문
// if(!checkRule2) { // rule2를 거쳤는데 그 안에 두단어이상 일 경우 > aAAbAbAbAa > A AAAA 이 되는데 모든 규칙은 한 단어에만 적용!!
// invalid(); // >> 이건 안해도 테스트는 통과된다. 단, oGOaOaGaLaEo > invalid 여야하는데 OOGLE로 통과됨. > G OOGLE 아닌 이유 : nolower 에서 rule2 체크함 but, 그냥 return이라 안됨.
// return;
// }
noLower(sentence, firstIndex);
}
String lowerStr = Character.toString(lower);
String resentence = sentence.substring(firstIndex, lastIndex);
String removeLower = resentence.replaceAll(lowerStr, "");
// AaAAAaAaAaAAAAaA 이런경우 방지 > rule1 만족하려면, 소문자 x 문장길이 * 2 - 원본문자 = 1 만족해야함.
if(removeLower.length() * 2 - resentence.length() != 1) {
invalid();
return;
}
checkRule1 = false; //rule1 두번 이상 방지 체크
checkRule2 = false;
lowerCheck(removeLower);
checkRule1 = true;
checkRule2 = true;
answer(removeLower);
resentence = sentence.substring(lastIndex); // 남은 뒷단어 체크
if(resentence.length()!=0) {
lowerCheck(resentence);
}
}
public void rule2(int firstIndex, int lastIndex, String sentence, char lower) {
// rule2 두번째 || 대문자 없는 것 방지 > aa
if(!checkRule2 || firstIndex == lastIndex ) {
invalid();
return;
}
String resentence = sentence.substring(firstIndex, lastIndex); // 다른 소문자 있는지 체크
String sentenceLower = resentence.toUpperCase();
// 다른 소문자 있는경우, rule2 수행 한 문장으로 lowerCheck()
if(!resentence.equals(sentenceLower)) {
checkRule2 = false;
lowerCheck(resentence);
}else {
answer(resentence);
}
resentence = sentence.substring(lastIndex+1); // 남은 문자열 수행
lowerCheck(resentence);
}
반응형
'Algorithm > Programmers' 카테고리의 다른 글
[Programmers/Lv.3] 야근 지수 - Java (0) | 2022.12.23 |
---|---|
[Programmers/Lv.3] 최고의 집합 - Java (0) | 2022.12.08 |
[Programmers/Lv2] 더 맵게 (0) | 2021.10.05 |
[Programmers/위클리 챌린지] 1주차_부족한 금액 계산하기 - Java (0) | 2021.09.09 |
[Programmers/2018 KAKAO BLIND RECRUITMENT] 캐시 - Java (0) | 2021.08.19 |
댓글