<문제 제시>
<문제설명>
문자열 s가 입력되었을 때 다음 규칙을 따라서 이 문자열을 여러 문자열로 분해하려고 합니다.
먼저 첫 글자를 읽습니다. 이 글자를 x라고 합시다.
이제 이 문자열을 왼쪽에서 오른쪽으로 읽어나가면서, x와 x가 아닌 다른 글자들이 나온 횟수를 각각 셉니다.
처음으로 두 횟수가 같아지는 순간 멈추고, 지금까지 읽은 문자열을 분리합니다.
s에서 분리한 문자열을 빼고 남은 부분에 대해서 이 과정을 반복합니다. 남은 부분이 없다면 종료합니다.
만약 두 횟수가 다른 상태에서 더 이상 읽을 글자가 없다면, 역시 지금까지 읽은 문자열을 분리하고, 종료합니다.
문자열 s가 매개변수로 주어질 때, 위 과정과 같이 문자열들로 분해하고,
분해한 문자열의 개수를 return 하는 함수 solution을 완성하세요.
<예시 입출력>
<문제 해결 과정>
문제를 먼저 이해하는 것이 필요했다.
"banana"일 경우, x를 첫문자로 기준잡는다.
x는 'b'이며, x인 문자가 나오는 숫자 카운트를 target,
x가 아닌 문자가 나오는 것은 non_target 으로 한다면
(target == non_target) 일때 문자열을 잘라내면된다.
ex) banana일때,
b 탐색) target = 1, non_target = 0
a 탐색) target = 1, non_target = 1
>> "ba" 가 잘려진다.
ex) aaabbaccccabba 일때,
a 탐색) target = 1, non_target = 0
a 탐색) target = 2, non_target = 0
a 탐색) target = 3, non_target = 0
b 탐색) target = 3, non_target = 1
b 탐색) target = 3, non_target = 2
a 탐색) target = 4, non_target = 2
c 탐색) target = 4, non_target = 3
c 탐색) target = 4, non_target = 4
>> "aaabbacc" 가 잘려진다.
Try 1)
public static int solution(String s) {
int answer = 0;
List<Integer> arr = new ArrayList<>();
char x = s.charAt(0);
System.out.println("기준 문자 = " + x);
// 횟수를 셀 변수
int cnt = 0;
for(int i = 0; i < s.length(); i++) {
// 첫문자는 초기값이 1
if(i == 0) {
cnt++;
arr.add(0, cnt);
}
// 첫문자와 다른 문자가 감지되었을때,
if(x != s.charAt(i)) {
// 달라졌을때의 cnt값을 비교해야함
cnt++;
arr.add(i, cnt);
System.out.println("x와 같지 않은 조건문 >> arr = " + arr);
System.out.println("s.charAt(i) = " + s.charAt(i));
}
// 첫문자와 같을 경우 cnt값을 증가시켜 저장 (다만 첫인덱스와 구분하기위해 i > 0 조건문 삽입
else if(x == s.charAt(i) && i > 0) {
cnt++;
arr.add(0, cnt);
}
// 첫문자의 횟수와 쌓인 부분의 횟수를 비교하여 같으면 answer++;
if(arr.get(0) == arr.get(i)) {
answer++;
}
// 횟수 연산이 끝날때마다 cnt 변수를 초기화해줌
cnt = 0;
}
return answer;
}
값이 불일치하여 오답이었다.
Solution 1)
// 첫 문자를 x라고 지정
// x가 아닌 문자가 오면 횟수가 1, 1번이므로
// 이렇게 횟수가 같아지는 순간이 오면 result값 +1 증가
<전체코드>
import java.util.ArrayList;
import java.util.List;
public class divide_string {
public static int solution(String s) {
int answer = 0;
List<String> arr = new ArrayList<>();
// 비교군 (x = 첫문자)
int a = 0;
// 비교군 (비교대상)
int b = 0;
// 문자열 길이가 0보다 긴 경우 무한반복
while(s.length() > 0) {
// 횟수 매번 초기화
int cnt = 0;
for(int i = 0; i < s.length(); i++) {
// 첫문자와 비교군문자가 같으면
if(s.charAt(0) == s.charAt(i)) {
// 비교군 첫문자의 카운트를 증가
a += 1;
}
else {
// 비교대상 문자의 카운트를 증가
b += 1;
}
// 만약 '비교군 첫문자 = a' 카운트와 '비교대상 문자 = b' 카운트가 같으면
if(a == b) {
// 해당 인덱스에 +1을 더한 후 for문을 종료
cnt = i + 1;
break;
}
}
// 문자열 잘라내기, 첫인덱스부터 cnt 인덱스 까지 잘라서 리스트에 저장
arr.add(s.substring(0, cnt));
// 연산할 문자열 새롭게 업데이트, cnt 인덱스부터 시작되는 문자열을 새로 만듦
s = s.substring(cnt);
// 만약 cnt값이 0이면 while문을 종료
if(cnt == 0) break;
}
// 잘라낸 문자열을 담은 리스트의 size()를 answer에 저장 후 return
answer = arr.size();
return answer;
}
public static void main(String[] args) {
String s = "banana";
System.out.println(solution(s));
}
}
while(s.length() > 0) 을 통해 문자열 길이가 0이될 때까지 반복하고,
첫번째 문자와 비교문자가 같을때 기준이되는 첫번째문자의 카운트를 증가시킨다 ( a++)
아닐 경우에는 기준과 다른 문자의 카운트를 증가시킨다. (b++)
a == b 일 경우
cnt값을 i + 1로 초기화 후 break한다.
리스트에 substring()메서드를 통하여 (0, cnt) 인덱스를 잘라 저장한다.
검사할 문자열을 잘려진 문자열로 업데이트 후 cnt값이 0일때의 예외사항도 처리해준다.
substring()으로 문자열을 잘라내가며 반복해야겠다고 생각했지만, a == b가 일치하는 등의 로직을 한번에 생각해내지 못해 조금 시간이 걸렸던 문제였다.
문제링크)
https://school.programmers.co.kr/learn/courses/30/lessons/140108
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
'Algorithms > 프로그래머스' 카테고리의 다른 글
[프로그래머스] '달리기 경주' - Java (0) | 2023.05.21 |
---|---|
[프로그래머스] '명예의 전당 (1)' - Java (0) | 2023.05.21 |
[프로그래머스] '겹치는 선분의 길이' - Java (1) | 2023.05.20 |
[프로그래머스] '평행' - Java (1) | 2023.05.19 |
[프로그래머스] '외계어 사전' - Java (0) | 2023.05.18 |