코딩테스트 연습 - 이상한 문자 만들기
문제 설명
- 매개변수 : 문자열
s
- 한 개 이상의 단어로 구성
- 하나 이상의 공백문자로 구분
- 리턴값 : 각 단어의 짝수번째 알파벳 → 대문자로, 홀수번째 알파벳 → 소문자로 바꾼 문자열
- 문자열 전체 짝/홀 인덱스가 아닌, 각 단어 기준 짝/홀 인덱스 판단
- 첫번째 글자 → 0번째 인덱스 → 짝수번째
설계
#1
- StringBuilder 를 만든다.
- 문자열
s
를 단어별로 쪼개서 String[] A 에 담는다. → split(" ")
- String[] A 에 있는 String 문자열을 한 글자씩 잘라서 또 다른 String[] B 에 담는다. →
split(””)
- String[] B 를 하나씩 돌면서 짝수 인덱스면 대문자(
toUpperCase()
), 홀수 인덱스면 소문자(toLowerCase()
)로 만들어 StringBuilder 에 넣는다.
- String[] B 반복문이 끝나면 한 단어가 끝났으므로 StringBuilder에 공백문자를 추가해준다.
- 모든 반복문이 끝났을 때 StringBuilder 마지막에 추가된 공백문자는 불필요하므로 빼준다.(
sb.setLength(sb.length() - 1);
)
- 만약 공백문자가
s
문자열 마지막에 붙어 있는 경우도 있으니, 문자열 s
뒤에서부터 공백 문자의 개수를 카운트한다.
- 6번에서 만든 StringBuilder 에 카운트만큼 공백 문자를 추가한다.
- StringBuilder를 String으로 바꾸어 리턴한다.
#2
- StringBuilder 를 만든다.
- 문자열
s
를 단어별로 쪼개서 String[] A 에 담는다.
- String[] A 에서 한 글자씩 담긴 원소들을 하나씩 비교한다.
- index 번째가 공백문자라면, cnt는 0, 아니라면 cnt + 1을 넣는다.
- cnt 가 홀수라면 소문자로, 짝수라면 대문자로 만들고 StringBuilder 에 넣는다.
- StringBuilder를 String으로 바꾸어 리턴한다.
코드
#1
class Solution {
public String solution(String s) {
StringBuilder sb = new StringBuilder();
String[] strArr = s.split(" ");
for (String str : strArr) {
String[] strArr2 = str.split("");
int idx = 0;
for (String str2 : strArr2) {
if (idx % 2 == 0)
sb.append(str2.toUpperCase());
else
sb.append(str2.toLowerCase());
idx++;
}
sb.append(" ");
}
sb.setLength(sb.length() - 1);
int spaceFromBack = 0;
String[] arrForFindSpace = s.split("");
for (int i = arrForFindSpace.length - 1; i >= 0; i--) {
if (arrForFindSpace[i].equals(" "))
spaceFromBack++;
else
break;
}
for (int i = 0; i < spaceFromBack; i++)
sb.append(" ");
return sb.toString();
}
}
#2
class Solution1 {
public String solution(String s) {
StringBuilder sb = new StringBuilder();
String[] strArr = s.split("");
int cnt = 0;
for (String str : strArr) {
cnt = (str.equals(" ")) ? 0 : cnt + 1;
if (cnt % 2 == 0)
sb.append(str.toUpperCase());
else
sb.append(str.toLowerCase());
}
return sb.toString();
}
}
시간 복잡도
- Solution → O(n^2)
- Solution1 → O(n)
어려웠던 점
- 처음에 문자열
s
에서 마지막에 공백이 있을 수도 있다는 것을 고려하지 않고, #1의 1~6번까지 설계하고 구현했었다. 테스트를 통과하지 못해 예외 케이스를 찾았더니 문자열 마지막에 공백이 들어 있는 경우 처리가 안되어 있었다. 뒤늦게 설계 7~8번을 만들어 문자열 뒤에 있는 공백을 세어 StringBuilder에 붙이려고 하다보니 코드가 간결하지 못하고 설계도 효율적이지 않게 되었다.
- #2처럼 처음부터 한글자씩 분리해서 공백인 경우는 cnt를 0으로, 공백이 아닌 경우는 cnt + 1로 카운트를 해주면 간단하게 풀린다.