Algorithm/Baekjoon(Java)

[백준/JAVA] 1316 : 그룹 단어 체커 ( prev = 0 )

비망노트 2022. 7. 29. 23:43
문제

그룹 단어란 단어에 존재하는 모든 문자에 대해서, 각 문자가 연속해서 나타나는 경우만을 말한다.

예를 들면, ccazzzzbb는 c, a, z, b가 모두 연속해서 나타나고,

kin도 k, i, n이 연속해서 나타나기 때문에 그룹 단어이지만,

aabbbccb는 b가 떨어져서 나타나기 때문에 그룹 단어가 아니다.

 

단어 N개를 입력으로 받아 그룹 단어의 개수를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 단어의 개수 N이 들어온다. N은 100보다 작거나 같은 자연수이다.

둘째 줄부터 N개의 줄에 단어가 들어온다. 단어는 알파벳 소문자로만 되어있고 중복되지 않으며, 길이는 최대 100이다.

 

출력

첫째 줄에 그룹 단어의 개수를 출력한다.

예제 입력 예제 출력
3
happy
new
year
3
4
aba
abab
abcabc
a
1
5
ab
aa
aca
ba
bb
4
2
yzyzy
zyzyz
0
1
z
1

 

⭕ 풀이

import java.util.*;
import java.io.*;

public class Main{
    
    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int tc = Integer.parseInt(br.readLine());
        
        StringBuilder sb = null;
        int count =0, w =0;
        while(w<tc){
            Set<Character> set = new HashSet<Character>();
            sb = new StringBuilder();
            char[] chArr = (br.readLine()).toCharArray();
            
            if(chArr.length==1){
                count++;
            }else{
                char startCh = ' ';
                for(int i=0;i<chArr.length;i++){
                   set.add(chArr[i]);
                   if(startCh!=chArr[i]){
                        sb.append(chArr[i]);
                   }
                   startCh=chArr[i];
                }
                if(sb.length()==set.size()){
                count++;
                }
            }
            w++;
        }
        System.out.print(count);
    }
}

✅ 예를들어 aabbcccb 가 있다면

set은 중복값이 들어갈 수 없다, 즉 set에 해당 문자열을 하나하나 다 넣으면 abc가 될것이고

이전 인덱스를 인덱스와 비교해 같지않다면 인덱스의 값을 sb에 넣는식으로 for문을 진행한다면

StringBuilder sb 에는 abcb가 들어있을것이다.

 

이렇게 진행해 sb의 길이와 set의 사이즈를 비교해서 길이가 같다면 그룹단어인것이므로

count++ 를 진행해준다

 

char startCh = ' '; 를 만들어주는 이유는

Node.js와 다르게 자바에서 [-1] 인덱스값을 비교하려하면 에러가 발생하므로

-1 대신 ' '를 만들어주어 0인덱스의 값도 넣을 수 있게하기위해 작성했다.

 

 

✅ 다른분의 풀이

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static BufferedReader br;

    public static void main(String[] args) throws IOException {

        br = new BufferedReader(new InputStreamReader(System.in));

        int n = Integer.parseInt(br.readLine());

        int count = 0;
        for (int i = 0; i < n; i++) {
            if (check() == true) {
                count++;
            }
        }
        System.out.println(count);
    }

    public static boolean check() throws IOException {
        boolean[] check = new boolean[26];
        int prev = 0;

        String str = br.readLine();

        for (int i = 0; i < str.length(); i++) {
            int now = str.charAt(i);

            if (prev != now) {
    
                if (check[now - 'a'] == false) {
                    check[now - 'a'] = true;
                    prev = now;
                } else {
                    return false;
                }
            }
        }
        return true;
    }
}

✅ check 함수

알파벳이 26개이므로 26길이의 boolean형 배열을 만든다. boolean의 기본형은 false 이므로 [0]~[25]까지 모두 false가 들어간다

int형 prev = 0 으로 만들어주었다. 이후 for문으로 들어가서 now = str.charAt(i);

어떤 알파벳이든 now에 charAt으로 들어올것이기때문에 now의 값이 0이 될수는 없다.

즉 prev != now는 처음에 무조건 if문조건을 충족할 수 밖에없다.

자바는 node.js처럼 [-1]인덱스와 [0]인덱스를 비교하지 못하므로 char startCh = ' '; 를 만들어준것과 비슷한 맥락이다.

이후 now에서 'a'를 뺀다 

만약 aabbcccb 를 입력받았다면 첫now는 a의 int 97이 될것인데 여기서 'a' 즉 97 을 가리키므로

now - 'a' 는 0이된다 check배열은 현재 모두 false로 초기화 되어있는 상태이므로 check[0] == false를 충족해

check[0]을 true로 바꾸고 prev = now 97이 된다.

 

다음for문 prev는 97이고 now도 97을 가져왔다. prev != now를 만족하지 못했다.

prev는 아직 97인 상태이다

 

다음for문 prev는 97이고 now는 b 즉 98을가져왔다. prev != now를 만족했고

98 - 'a' = 1 check[1]자리도 false이므로 true로 바꾸고

prev = 98 이 된다.

 

즉 이전값이 같은 값이라면 건너뛰고 같지않을 경우에만 check[idx]를 true로 바꾼다.

 

쭉 반복하다가 aabbcccb 에서 

이전값인 c와 now에 들어간 b는 같지 않으므로 prev != now ( 99!=98 )를 만족해서

98-'a' = 1 check[1]의 자리가 false이면 true로 바꾸어야하는데 이미 전에 true로 바꾸어놨었으므로

else의 return false; 를 실행시킨다.

즉 false가 반환되었으므로 main메서드에서의 count++는 할 수 없다. 즉 그룹단어가 아니라는것이다.

 

마지막에 b가 없었다면 체크 메서드의 마지막에있는 return true; 가 실행되어

true를 반환하고 그룹단어를 카운트하는 main메서드에서 count++ 가 실행되었을것이다.

 

 

 

-출처

https://www.acmicpc.net/problem/1316