https://www.acmicpc.net/problem/1316
1316번: 그룹 단어 체커
그룹 단어란 단어에 존재하는 모든 문자에 대해서, 각 문자가 연속해서 나타나는 경우만을 말한다. 예를 들면, ccazzzzbb는 c, a, z, b가 모두 연속해서 나타나고, kin도 k, i, n이 연속해서 나타나기 때
www.acmicpc.net
문제
그룹 단어란 단어에 존재하는 모든 문자에 대해서, 각 문자가 연속해서 나타나는 경우만을 말한다. 예를 들면, ccazzzzbb는 c, a, z, b가 모두 연속해서 나타나고, kin도 k, i, n이 연속해서 나타나기 때문에 그룹 단어이지만, aabbbccb는 b가 떨어져서 나타나기 때문에 그룹 단어가 아니다.
단어 N개를 입력으로 받아 그룹 단어의 개수를 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 단어의 개수 N이 들어온다. N은 100보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에 단어가 들어온다. 단어는 알파벳 소문자로만 되어있고 중복되지 않으며, 길이는 최대 100이다.
출력
첫째 줄에 그룹 단어의 개수를 출력한다.
첫 번째 시도
package ex1;
import java.io.*;
import java.lang.*;
import java.util.*;
public class ex1 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int a = Integer.parseInt(br.readLine());
int p = 0;
int[] check = new int[26];
ArrayList<String> line = new ArrayList<>();
int count = 0;
boolean bool = false;
for (int i = 0; i < a; i++) {
line.add(br.readLine());
}
// 한 줄 반복문
for (int i = 0; i < line.size(); i++) {
// 알파벳 체크 초기화
for (int j = 0; j < line.get(i).length(); j++) {
check[j] = 0;
}
// 줄 글자 반복문
for (int j = 0; j < line.get(i).length() - 1; j++) {
int k = j + 1;
if (k < line.get(i).length()) {
if (line.get(i).charAt(j) == line.get(i).charAt(k)) {
check[(int) line.get(i).charAt(j) - 97] = 1;
continue;
} else if (line.get(i).charAt(j) != line.get(i).charAt(k)
&& check[(int) line.get(i).charAt(k) - 97] == 0) {
check[(int) line.get(i).charAt(j) - 97] = 1;
check[(int) line.get(i).charAt(k) - 97] = 1;
} else if (line.get(i).charAt(j) != line.get(i).charAt(k)
&& check[(int) line.get(i).charAt(k) - 97] == 1) {
bool = true;
}
}
}
if (bool) {
count++;
bool = false;
}
for (int l = 0; l < check.length; l++) {
// System.out.print(check[l] + " ");
check[l] = 0;
}
}
System.out.print(a - count);
}
}
- 위의 코드를 실행했을 때 런타임 에러 (ArrayIndexOutOfBounds) 발생
아래 코드로 수정 후 에러가 사라졌다.
두 번째 시도
package ex1;
import java.io.*;
import java.lang.*;
import java.util.*;
public class ex1 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int a = Integer.parseInt(br.readLine());
int p = 0;
ArrayList<String> line = new ArrayList<>();
int count = 0;
boolean bool = false;
if (a <= 100) {
for (int i = 0; i < a; i++) {
line.add(br.readLine());
}
// 한 줄 반복문
for (int i = 0; i < line.size(); i++) {
if (line.get(i).length() == 1 || line.get(i).length() == 2) {
} else if (line.get(i).length() > 2) {
// 줄 글자 반복문
for (int j = 0; j < line.get(i).length(); j++) {
if (j + 1 < line.get(i).length() && line.get(i).charAt(j) == line.get(i).charAt(j + 1)) {
continue;
} else {
for (int k = j + 1; k < line.get(i).length(); k++) {
if (line.get(i).charAt(j) == line.get(i).charAt(k)) {
bool = true;
break;
}
}
}
}
}
if (bool) {
count++;
bool = false;
}
}
System.out.print(a - count);
} else
return;
}
}
- 위 코드를 작성할 때 아래의 코드를 참고했다.
package ex1;
import java.io.*;
class ex2 {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int a = Integer.parseInt(br.readLine());
int count = 0;
for (int i=0; i<a; i++) {
String s = br.readLine();
for (int k=0; k<s.length(); k++) {
int x = 0;
if (k+1 != s.length() && s.charAt(k) == s.charAt(k+1))
continue;
else {
for(int j=k+1; j<s.length(); j++) {
if(s.charAt(k) == s.charAt(j))
x++;
}
}
if(x>=1) {
count++;
break;
}
}
}
bw.write(String.valueOf(a - count));
bw.newLine();
bw.flush();
bw.close();
}
}
해결 방법
- 처음 했던 방법은 주어진 N개의 단어를 for 문으로 반복하여 단어의 맨 앞자리부터 읽어왔다. 읽어온 단어에 포함된 알파벳에 따라 중복에 상관없이 크기가 26인 정수형 배열 check에 a~z의 인덱스 순서대로 0을 넣어 초기화 했다. 그리고 단어를 문자 단위로 나눠서(charAt 사용) 하나씩 비교했다. 방문한 문자는 알파벳 순서에 맞게 check 배열 인덱스를 참조하여 1로 값을 변경했다. 불러온 알파벳이 다음 인덱스에 올 알파벳와 다르고, 다음 알파벳에 해당되는 인덱스의 check 배열을 확인하여 1이면 true 값을 통해 break 후 count++을 하여 개수를 저장했다.
- 이 방법을 사용했을 때 이클립스에선 동작했지만, 코딩 문제 제출 페이지에서는 런타임 에러 (ArrayIndexOutOfBounds)가 발생해서 다른 소스코드를 참고해서 불필요한 check 배열을 없애고, 다음에 올 문자(알파벳)을 체크할 때 Array Index 참조 오류가 나지 않도록 if문의 조건을 ArrayList의 length() 보다 작으면 실행되도록 했다.
어려웠던 점 / 고쳐야할 점
- 원래 작성했던 코드에서 ArrayList의 인덱스를 넘는 범위를 참조하는 곳이 어딘지 확인하려고 했는데, 내가 작성한 코드인데도 헷갈렸다. 코드를 좀 더 알아보기 쉽게 작성해야겠다.
반응형
'알고리즘 문제 풀이 (Problem Solving)' 카테고리의 다른 글
[Problem Solving/Java] 백준 4948번 - 베르트랑 공준 (2) | 2024.01.02 |
---|---|
[Problem Solving/Java] 백준 1929번 - 소수 구하기 (0) | 2024.01.02 |
[Problem Solving/Java] 백준 2581번 - 소수 (0) | 2023.08.30 |
[Problem Solving/Java] 백준 1978번 - 소수 찾기 (0) | 2023.08.30 |
[Problem Solving/Java] 백준 1712번 - 손익분기점 (0) | 2023.08.30 |