제목 : 그룹 단어 체커 (no.1316)
문제 출처
문제
그룹 단어란 단어에 존재하는 모든 문자에 대해서, 각 문자가 연속해서 나타나는 경우만을 말한다. 예를 들면, ccazzzzbb는 c, a, z, b가 모두 연속해서 나타나고, kin도 k, i, n이 연속해서 나타나기 때문에 그룹 단어이지만, aabbbccb는 b가 떨어져서 나타나기 때문에 그룹 단어가 아니다.
단어 N개를 입력으로 받아 그룹 단어의 개수를 출력하는 프로그램을 작성하시오.
Input
첫째 줄에 단어의 개수 N이 들어온다. N은 100보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에 단어가 들어온다. 단어는 알파벳 소문자로만 되어있고 중복되지 않으며, 길이는 최대 100이다.
Output
첫째 줄에 그룹 단어의 개수를 출력한다.
Ex.Input 1
3
happy
new
year
Ex.Output 1
3
Ex.Input 2
4
aba
abab
abcabc
a
Ex.Output 2
1
Ex.Input 3
5
ab
aa
aca
ba
bb
Ex.Output 3
4
Ex.Input 4
2
yzyzy
zyzyz
Ex.Output 4
0
Ex.Input 5
1
z
Ex.Output 5
1
Ex.Input 6
9
aaa
aaazbz
babb
aazz
azbz
aabbaa
abacc
aba
zzaz
Ex.Output 6
2
Code
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner xx = new Scanner(System.in);
int deep = xx.nextInt();
// 그룹단어가 아닌경우 --로 하나하나씩 카운트가 빠지는 구조라 초기값을 입력개수 N으로 설정해주었다.
int count = deep;
for(int i = 0; i < deep; i++){
String st = xx.next();
// 알파벳의 개수가 26개 이기에 boolean[26]을 하였다.(디폴트 값은 false)
boolean check[] = new boolean[26];
// lenght-1을 해야지 j+1과 비교할 수 있다.
for(int j = 0; j < st.length() - 1; j++) {
// 연속된 경우가 아닐 때(지정된 인덱스에 해당하는 값과 그 다음값을 비교하여 다를경우)
if(st.charAt(j) != st.charAt(j + 1)) {
// 아까 나왔던 단어가 또 나왔을 때 (true자리에 또 true가 온 경우)
if(check[st.charAt(j + 1) - 97] == true) {
count--;
// 한번 그룹 단어가 아닌놈은 영원히 그룹단어가 아니기에 뒤엔 볼필요도 없어서 바로 break로 빠져나오는 모습이다.
break;
}
}
// 연속되는 경우이거나, 연속되진 않았는데 나왔던 단어가 아닌 처음나왔던 단어인경우 => false에서 true로 변경해 준다.
// 여기서 - 97을 한 이유는 아스키코드로 소문자a가 97이니 -97을 하여 a의 인덱스 값을 0으로 만들어 주기 위함이다.
check[st.charAt(j) - 97] = true;
}
}
// 답 출력
System.out.println(count);
}
}
풀이 방법
이문제는 결국 아닌걸 찾으면 된다
그룹단어가 맞는 조건은
1.연속된 문자로만 나왔을 때
2.아무것도 겹치지 않은 문자로만 나왔을 때
3.연속된 부분도 있고, 연속되지 않은 문자도 있는데 연속된 것 또는 연속되지 않은 것이 한칸 이상 뛰고 또 나오지 않을때
4.연속되지 않은 문자로만 있는데 앞서 나왔던 문자가 한칸 이상 뛰고 또 나오지 않을 때
따라서 그룹 단어가 맞는걸 카운터 하려니 맞는 조건이 많아 쉽지가 않고
그룹 단어가 아닌 조건은
1.연속된 경우가 아닌 아까 나왔던 단어가 또 나올 때
이 한가지 경우만 그룹단어가 아니기에
그룹 단어가 아닌 경우 -- 를 해주면 좀더 쉽게 풀 수 있다.
좀더 자세한 설명은 한줄한줄 설명하도록 하겠다.(주석으로 해놨다)
설명
int count = deep;
그룹단어가 아닌경우 --로 하나하나씩 카운트가 빠지는 구조라 초기값을 입력개수 N으로 설정해주었다.
boolean check[] = new boolean[26];
알파벳의 개수가 26개 이기에 boolean[26]을 하였다.(디폴트 값은 false)
for(int j = 0; j < st.length() - 1; j++) {
lenght-1을 해야지 j+1과 비교할 수 있다.
if(st.charAt(j) != st.charAt(j + 1)) {
[첫번째 IF문]연속된 경우가 아닐 때(지정된 인덱스에 해당하는 값과 그 다음값을 비교하여 다를경우)
if(check[st.charAt(j + 1) - 97] == true) {
count--;
[두번째 IF문]아까 나왔던 단어가 또 나왔을 때 (true자리에 또 true가 온 경우)
break;
한번 그룹 단어가 아닌놈은 영원히 그룹단어가 아니기에 뒤엔 볼필요도 없어서 바로 break로 빠져나오는 모습이다.
check[st.charAt(j) - 97] = true;
(두번째 IF문만 만족하지 않은경우)연속되는 경우이거나, 연속되진 않았는데 나왔던 단어가 아닌 처음나왔던 단어인경우 => false에서 true로 변경해 준다.
여기서 - 97을 한 이유는 아스키코드로 소문자a가 97이니 -97을 하여 a의 인덱스 값을 0으로 만들어 주기 위함이다.
티스토리와 깃허브 홈
오류나 궁금하신점은
아래 댓글로 알려주시면 감사하겠습니다.
'백준' 카테고리의 다른 글
[JAVA] 백준 2444. (0) | 2023.10.11 |
---|---|
[JAVA] 백준 10988. (0) | 2023.10.10 |
[JAVA] 백준 3052. (0) | 2023.10.05 |
[JAVA] 백준 10813. (1) | 2023.10.05 |
[JAVA] 백준 10951. (2) | 2023.10.04 |