1) 문제 분석
두 가지 방법이 떠올랐다. 하나는 단어의 문자를 처음부터 하나씩 읽어가면서 따지는 것이고 다른 하나는 문자열에서 크로아티아 알파벳에 해당되는 부분을 알파벳이 아닌 문자(여기서는 “?”)로 전부 바꿔주고, 마지막에 이 문자열의 길이를 출력해주는 것이다. 첫 번째 방법은 C 스타일이고 두 번째 방법은 C++의 string 메소드들도 쉽게 해결해 줄 수 있다.
우선 두 번째 방법부터 보자면, 크로아티아 알파벳에 해당되는 문자열들(ex: “c=”, “nj”,…)을 배열에 넣어놓고, 이 배열의 각 원소(문자열)들이 입력된 단어에 들어가있는지 확인하고(find 메소드 사용) 그렇다면 이를 “?”로 바꿔준다(replace 메소드 사용). 예제 4번 처럼 같은 문자열이 한 단어에 여러 번 나타날 수 있으므로 find의 값이 입력 단어의 인덱스 범위를 넘어갈 때까지 같은 크로아티아 알파벳 문자열에 대해서 find 메소드를 반복해준다. 이 방법은 코드를 이해하기에도 쉽고 코드도 간결해지지만 단어가 훨씬 길어지고, 처리해야 하는 단어가 1개가 아니라 여러 개가 되면, find와 replace를 반복적으로 사용하기 때문에 효율이 떨어질 것 같았다.
따라서 대신 첫 번째 방법은, 단어를 입력 받으면 단어의 첫 문자부터 차례로 읽어나가면서 크로아티아 알파벳에 해당하는 문자들이 있으면 한 문자로 카운트하고 그 문자들 이후의 문자를 다시 읽어나가는 식으로 문자의 총 개수를 구하는 방법이다. 이렇게 되면 단어의 문자들을 정확히 한 번만 읽어도 되고 문자들을 바꿀 필요도 없다.
두 방법이 속도에서 어느 정도 차이 나는지 확인하기 위해 간단하게 실험을 해보았는데
ljes=njakljes=njakljes=njakljes=njakljes=njakljes=njakljes=njak
이라는 문자열에 대해 100번 반복하여 실행했을 때의 시간이 얼마나 걸리는지 측정해보았다(10번 반복). 첫 번째 방법은 (51, 45, 48, 27, 42, 28, 45, 39, 44, 30)ms가 나왔고, 두 번째 방법은 (510, 553, 645, 414, 585, 412, 418, 411, 545, 514)ms가 나왔다. 평균값을 계산해보면 각각 39.9ms와 500.7ms로 10배 이상의 차이가 있다.
2) 두 번째 방법 코드
#include<iostream>
#include <string>
using namespace std;
string alpha[] = {"c=", "c-", "dz=", "d-", "lj", "nj", "s=","z="};
int main(){
ios_base::sync_with_stdio(false);
string word;
cin >> word;
//replace all strings from alpha array with "?" in word
for(int i=0; i<8; i++){
int index = word.find(alpha[i]);
//repeat replacement until alpha[i] string appears no more
while(0<=index && index<word.length()){
//replace alpha[i] with "?"
word.replace(index, alpha[i].length(), "?");
index = word.find(alpha[i]);
}
}
//print out the length of the word
cout << word.length();
}
3) 첫 번째 방법 코드
#include<stdio.h>
int main(){
char word[102];
int count = 0; //total number of characters
int length; //length of the word
fgets(word, sizeof(word),stdin);
//find the length of the word
for(length=0; word[length]!='\n' && word[length]!='\0'; length++) ;
for(int i=0; i<length; i++){
switch(word[i]){
//"c=" or "c-"
case 'c':
if(i+1<length && (word[i+1]=='=' || word[i+1]=='-'))
i++; //skip one character
break;
//"dz="
case 'd':
if(i+2<length && word[i+1]=='z' && word[i+2]=='=')
i+=2; //skip two characters
else if(i+1<length && word[i+1]=='-')
i++; //skip one character
break;
//"lj" or "nj"
case 'l':
case 'n':
if(i+1<length && word[i+1]=='j')
i++; //skip one character
break;
//"s=" or "z="
case 's':
case 'z':
if(i+1<length && word[i+1]=='=')
i++; //skip one character
break;
}
//count one character
count++;
}
printf("%d",count);
}