문제
해결 방안 고민
== 크로아티아 알파벳 ==
č c=
ć c-
dž dz=
đ d-
lj lj
nj nj
š s=
ž z=
위 목록에 없는 알파벳은 한 글자씩 센다.
== 입력 ==
알파벳 소문자 + '-', '='
== 출력 ==
몇 개의 알파벳으로 이루어져있는지 출력
alphabet = {'c=', 'c-', 'dz=', 'd-', 'lj', 'nj', 's=', 'z='}
ljes=njak
replace => eak => 의 길이 + arrayList의 길이
'lj' e 's=' 'nj' a k
Markdown
복사
•
처음에는 배열을 생성하여 하나씩 순회하면서 동일한 것을 찾으면 되지 않을까 하는 생각을 했다.
•
찾은 것들을 ArrayList로 뺀 후에 arrayList의 길이와 replace 함수를 통해 가공된 문자열의 길이를 더하면 해결할 수 있지 않을까 하는 생각이 들었다.
•
하지만 굳이 ArrayList를 만들어서 진행할 필요가 있을까 싶었고, 결국 for문과 배열만으로 문제를 해결하려고 했지만 쉽게 풀리지 않았다.
해결 방법
•
크로아티아 알파벳은 한 개의 문자가 아닌 2개, 3개의 문자로 구성되어 있다. 그렇다면 하나의 문자로 간주할 수 있도록 하는 로직을 구성하여 작성해주어야 한다.
•
예를 들어 ‘c=’, ‘c-’라는 크로아티아 알파벳이 있다고 가정해보자. ch == ‘c’인 상황에서 str.charAt(i + 1) 즉, 다음 문자가 ‘=’이라면 i + 1까지가 하나의 문자이므로 다음 문자를 건너뛰기 위해 i를 1로 증가시키면 되는 것이다.
String str = input();
int count = 0;
for (int i = 0; i < str.length; i++) {
char ch = str.charAt(i);
if(ch == 'c') { // 만약 ch 가 c 라면?
if(str.charAt(i + 1) == '=') { //만약 ch 다음 문자가 '=' 이라면?
// i+1 까지가 하나의 문자이므로 다음 문자를 건너 뛰기 위해 1 증가
i++;
}
else if(str.charAt(i + 1) == '-') {
i++;
}
}
count++;
}
Java
복사
이런 식으로 말이다.
•
하지만 문제가 있다. 이런 형태로 작성을 하게 되다 보면 StringIndexOutOfBoundsException 이라는 에러에 직면하게 된다. 이는 참조할 수 없는 범위를 벗어날 때 발생하는 에러이다.
•
아래 그림을 보자
i가 10인 경우 str.charAt(10) 을 통해 ch에 저장되고 (ch = ‘c’) c라는 문자를 받았기 때문에 조건문을 실행시킨다. 그런데 if( str.charAt(i + 1) == '=' ) 이 조건을 충족시키지 못한다. 다음 문자가 존재하지 않기 때문이다.
그래서 이 문제를 해결하려면 i값이 현재 문자열의 길이(str.length)에서 -1 값보다 작을 경우에만 다음 조건문을 실행시키도록 작성해줘야 한다. dz=를 검사할 때는 i가 str.length - 2 보다 작아야 한다.
코드
•
실패 코드
package algo250226;
import java.io.*;
// 크로아티아 알파벳 - 실버 5
public class Baek2941 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String[] croatia = {"c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z="};
String str = br.readLine();
int count = 0;
int answer = 0;
int strLength = str.length();
int length = croatia.length;
for (int i = 0; i < length; i++) {
for (int j = 0; j < strLength; j++) {
if (croatia[i].equals(str.substring(j, j + 2))) {
str = str.replace(str.substring(j, j + 2), "");
count++;
break;
} else if (croatia[i].equals(str.substring(j, j + 3))) {
str = str.replace(str.substring(j, j + 3), "");
count++;
break;
}
}
}
answer = count + strLength;
bw.write(String.valueOf(answer));
bw.flush();
bw.close();
br.close();
}
}
Java
복사
•
성공 코드
package algo250226;
import java.io.*;
public class Baek2941_2 {
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 count = 0;
String str = br.readLine();
int length = str.length();
for (int i = 0; i < length; i++) {
char ch = str.charAt(i);
if (ch == 'c') { // ch가 c라면
if (i < length - 1) {
if (str.charAt(i + 1) == '=') { // 다음 문자가 '=' 이라면
i++; // i+1 까지가 하나의 문자여서 다음 문자를 건너 뛰기 위해 1 증가시킴
} else if (str.charAt(i + 1) == '-') {
i++;
}
}
} else if (ch == 'd') {
if (i < length - 1) {
if (str.charAt(i + 1) == 'z') { // dz일 경우
if (i < length - 2) {
if (str.charAt(i + 2) == '=') { // dz=일 경우
i += 2;
}
}
} else if (str.charAt(i + 1) == '-') { // d-일 경우
i++;
}
}
} else if (ch == 'l') {
if (i < length - 1) {
if (str.charAt(i + 1) == 'j') { // lj일 경우
i++;
}
}
} else if (ch == 'n') {
if (i < length - 1) {
if (str.charAt(i + 1) == 'j') { // nj일 경우
i++;
}
}
} else if (ch == 's') {
if (i < length - 1) {
if (str.charAt(i + 1) == '=') { // s=일 경우
i++;
}
}
} else if (ch == 'z') {
if (i < length - 1) {
if (str.charAt(i + 1) == '=') { // z=일 경우
i++;
}
}
}
count++;
}
bw.write(String.valueOf(count));
bw.flush();
bw.close();
br.close();
}
}
Java
복사
정리
이 문제를 통해 여러 개의 문자를 한 개의 문자로 봐야 하는 경우 어떻게 접근해야 하는지를 알 수 있었다. for문을 활용하는 방법은 다양하지만 정작 문제에 접근하는 방식에 있어서 아직도 범위가 넓지 못하다는 것을 느꼈다. 개발을 위한 성능 최적화 및 기능 개선을 할 수 있는데 도움을 줄 수 있는 공부가 알고리즘 공부라고 생각하지만 단순히 문제를 푸는 용도로만 알고리즘을 활용할 것이 아니라 실제 어떻게 적용하는 지를 바로 알아야 하는 것이 개발의 최종 목표가 아닌가 싶다.