有希
백준 2941/크로아티아 알파벳 본문
주의할 점은 2,3 글자가 하나의 글자로 치환된다는 점이다. 즉, 2,3글자마자 체크하여 치환된 문자가 아니라면 따로 세야한다.
예제입력1의 예시를 보면 lj / e / s= / nj / a / k 로 나뉘는데,
현재 e에서 시작하여 문자를 체크한다고 하면
e
es
es=
의 3가지가 가능하다.
case "e" : 2,3번째 글자를 체크해야하니 아무것도 하지 않고
case "es" : 2글자이므로 치환 문자에 속하는지 확인하고 맞다면 알파벳 개수를 1 증가시킨다.
아니라면 3글자일 수도 있으므로 아무것도 하지 않는다.
case "es=" 일 때에는 3글자이므로 치환 문자에 속하는지 확인하고 맞다면 알파벳 개수를 1증가시킨다.
아니라면 치환된 문자에 속하지 않는 첫번째 글자 단독으로 하나의 알파벳이므로 알파벳 개수를 1 증가시키고 =를 가리키고 있는 현재 pos를 -2하여 s부터 시작하도록 한다.
즉, 1번 예시의 문자열 탐색 순서를 나타내자면 다음과 같다. 알파벳 개수를 int ret이라 했을때,
l
lj (ret+=1)
e
es
es= (ret+=1)
s
s= (ret+=1)
n
nj (ret+=1)
a
ak
문제는 ak가 반영되지 않고 그대로 알고리즘이 끝난다는 점이다. 하지만 위의 알고리즘에 걸리지 않았다는 것은 개별 알파벳으로 이루어진 치환된 문자가 아니므로, ak의 사이즈를 그대로 더해주면 된다. 코드는 아래와 같다.
#include <iostream>
#include <unordered_set>
#include <string>
using namespace std;
int main() {
unordered_set<string> croatia;
croatia.insert("c=");
croatia.insert("c-");
croatia.insert("dz=");
croatia.insert("d-");
croatia.insert("lj");
croatia.insert("nj");
croatia.insert("s=");
croatia.insert("z=");
string input;
getline(cin, input);
int ret = 0;
string make = "";
for (size_t i = 0; i < input.size(); ++i) {
make += input[i];
if (make.size() == 2) {
if (croatia.find(make) != croatia.end()) {
ret++;
make = "";
}
}
else if (make.size() == 3) {
if (croatia.find(make) != croatia.end()) {
ret++;
make = "";
}
else {
ret++;
i -= 2;
make = "";
}
}
}
ret += make.size();
cout << ret << endl;
return 0;
}
파이썬의 경우에는 replace함수가 간단하게 찾아서 치환해주는 것을 한다.
croatia 리스트의 원소를 x로 순회하며 word에서 x를 찾아서 *로 치환한다.
ljes=njak 의 경우에는 *e**ak 로 바뀐다. 물론 메모리나 속도는 위에 비해 굉장히 낭비가 심하다.
word = input()
croatia = ['c=','c-','dz=','d-','lj','nj','s=','z=']
for x in croatia:
word = word.replace(x,'*')
print(len(word))
'프로그래밍 > 알고리즘+코딩테스트' 카테고리의 다른 글
백준 11719/그대로 출력하기 2 (0) | 2022.08.03 |
---|---|
백준 10773/제로 (0) | 2022.08.03 |
HackerRank/Subarray Division (0) | 2022.05.08 |
HackerRank/Between Two Sets (0) | 2022.05.03 |
HackerRank/Number Line Jumps (0) | 2022.05.02 |