이번에는 백준 14405번 피카츄 문제를 풀어보았습니다.
문제를 처음 봤을 때 문자열을 앞에서부터 읽으면서 "pi", "ka", "chu" 중 하나와 일치하는지만 확인하면 된다고 생각했습니다.
현재 위치에서 세 가지 문자열 중 하나가 시작되는지 확인하고, 일치한다면 해당 길이만큼 이동하는 방식으로 구현하였습니다.
이후에는 substr()을 이용하여 조금 더 간단하게 구현해보았습니다.
피카츄는 다음 세 음절만 발음할 수 있습니다.
"pi""ka""chu"주어진 문자열이 위 세 음절만을 이어 붙여 만들 수 있는 문자열인지 판별하는 문제입니다.
현재 문자를 확인하여
p라면 "pi"k라면 "ka"c라면 "chu"를 만족하는지 직접 검사하였습니다.
일치하면 해당 문자열 길이만큼 인덱스를 이동하고, 그렇지 않으면 발음할 수 없는 문자열이라고 판단하였습니다.
같은 로직을 substr()을 이용하여 구현하였습니다.
현재 위치에서 "pi", "ka", "chu"와 같은지만 비교하면 되므로 코드가 훨씬 단순해졌습니다.
#include <bits/stdc++.h>
using namespace std;
string s;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> s;
bool ret_flag = true;
if (s.length() == 1)
ret_flag = false;
for (int i=0; i<s.length()-1; i++) {
if (s[i] == 'p') {
if (s[i+1] == 'i' && i != s.length()-3)
i++;
else
ret_flag = false;
}
else if (s[i] == 'k') {
if (s[i+1] == 'a' && i != s.length()-3)
i++;
else
ret_flag = false;
}
else if (s[i] == 'c') {
if (i != s.length()-2 && s[i+1] == 'h' && s[i+2] == 'u')
i += 2;
else
ret_flag = false;
}
else {
ret_flag = false;
}
}
if (ret_flag)
cout << "YES\n";
else
cout << "NO\n";
return 0;
}
pi, ka, chu 중 하나인지 검사합니다.현재 문자를 기준으로 어떤 문자열인지 판단하였습니다.
if (s[i] == 'p')
else if (s[i] == 'k')
else if (s[i] == 'c')
각 경우에 맞는 문자열을 직접 비교하도록 구현하였습니다.
각 문자열이 조건을 만족하는지 직접 확인하였습니다.
if (s[i+1] == 'i')
if (s[i+1] == 'a')
if (s[i+1] == 'h' && s[i+2] == 'u')
조건을 만족하지 않는 경우에는 바로 발음할 수 없는 문자열로 처리하였습니다.
현재 문자열을 정상적으로 읽었다면 해당 길이만큼 인덱스를 이동하였습니다.
i++;
또는
i += 2;
중복 검사 없이 다음 음절부터 확인하도록 구현하였습니다.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
string s;
cin >> s;
bool ret_flag = true;
for (int i = 0; i < s.length(); i++) {
if (i < s.length()-1 &&
(s.substr(i,2) == "pi" || s.substr(i,2) == "ka"))
i++;
else if (i < s.length()-2 &&
s.substr(i,3) == "chu")
i += 2;
else
ret_flag = false;
}
if (ret_flag)
cout << "YES\n";
else
cout << "NO\n";
return 0;
}
"pi" 또는 "ka"인지 확인합니다."chu"인지 확인합니다.현재 위치의 문자열을 직접 잘라 비교하였습니다.
if (s.substr(i,2) == "pi")
if (s.substr(i,2) == "ka")
if (s.substr(i,3) == "chu")
문자를 하나씩 비교하는 것보다 코드가 훨씬 간단해졌습니다.
문자열이 일치하면 길이만큼 인덱스를 증가시켰습니다.
i++;
i += 2;
이미 확인한 문자열을 다시 검사하지 않도록 구현하였습니다.
substr()을 호출하기 전에 문자열 범위를 먼저 확인하였습니다.
if (i < s.length()-1)
if (i < s.length()-2)
문자열 범위를 벗어나는 경우가 발생하지 않도록 처리하였습니다.
V2는 V1과 동일한 로직이지만, substr()을 사용하여 문자열 비교를 단순화한 것이 핵심입니다.