Algorithms/프로그래머스

[프로그래머스] '문자열 나누기' - Java

LEFT 2023. 5. 20. 15:12

<문제 제시>

<문제설명>
문자열 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