BOJ/string

C++) 백준 4659, 비밀번호 발음하기

mhe1239 2024. 11. 16. 23:12
문제 링크
https://www.acmicpc.net/problem/4659

 

 

문제 내용

매 입력은 문자열이며 길이는 20이하다, end가 입력되면 끝낸다.

1. 모음(a,e,i,o,u) 하나를 반드시 포함하여야 한다.
2. 모음이 3개 혹은 자음이 3개 연속으로 오면 안 된다.
3. 같은 글자가 연속적으로 두번 오면 안되나, ee 와 oo는 허용한다.

이 규칙들이 지켜질 시에 <%s> is acceptable,

지켜지지 않을 시에 <%s> is not acceptable라고 출력한다.

 

코드

#include<iostream>//4659, 비밀번호 발음하기
#include<cstring>
using namespace std;
string s;
bool mo(string k) {
    for (unsigned short i = 0; i < k.length(); i++) {
        if (k[i] == 'a' || k[i] == 'e' || k[i] == 'i' || k[i] == 'o' || k[i] == 'u')
            return true;
    }
    return false;
}
bool mjsequence(string k) {
    int mocnt=0,jacnt=0;
    for (unsigned short i = 0; i < k.length(); i++) {
        if (strchr("aeiou", k[i]) != NULL){
            jacnt = 0;mocnt++;
            if (mocnt >= 3)
                return false;
        }else {
            mocnt = 0;jacnt++;
            if (jacnt >= 3)
                return false;
        }
    }
    return true;
}
bool sequence(string k) {
    for (unsigned short i = 0; i < k.length()-1; i++) {
        if (k[i] == k[i + 1]) {
            if (k[i] == 'e' || k[i] == 'o')
                return true;
            return false;
        }
        
    }
    return true;
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    for (;;) {
        cin >> s;
        if (s == "end")
            break;
        if (mo(s) && mjsequence(s) && sequence(s))
            cout << "<" << s << "> is acceptable.\n";
        else
            cout << "<" << s << "> is not acceptable.\n";
    }
}

 

풀이 및 분석

1번 규칙의 경우 모음인 a,e,i,o,u를 포함하면 되기에  for를 사용하여 string을 순회하면서 문자열 s가 a,e,i,o,u를 포함하는지 확인하면 된다.(mo함수)

2번 규칙의 경우 모음 or 자음이 3개 이상이 연속되면 false,  그 외의 경우에도 true이다.(mjsequence함수)

3번 규칙의 경우 같은 글자가 2개 이상이 연속되면 false, 하지만 e,o가 2개 이상 연속되면 true이다.(sequence함수)

 

std::string::length()의 반환 타입은 std::size_t이기에 for문의 i를 short가 아닌 std::size_t 또는 unsigned short, unsigned int 등의 선택지가 있기에 unsigned short를 택하였다.

그 외에 (int)k.length()와 같은 방법이 있다.

 

mjsequence함수에서 if (strchr("aeiou", k[i]) != NULL)부분의 strchr함수는 문자열을 나눠서 특정 문자를 찾는 라이브러리로, #include<cstring>를 필요로 한다. 즉, if (k[i] == 'a' || k[i] == 'e' || k[i] == 'i' || k[i] == 'o' || k[i] == 'u')와 같은 동작을 한다.

자음과 모음을 각각 3이상 연속되는지를 판단해야하기에 모음 or 자음이 연속되면 그에 맞는  cnt를 증가시키고, 이가 끊기면 그와 반대가 되는 cnt값을 0으로 다시 초기화시킴으로써 불연속된 것을 나타낸다.

 

sequence함수의 k.length() - 1의 경우 k.length()까지 순회할 경우 k[i + 1]를 확인하면 '\0'를 확인하는 것이기에  k.length() - 1를 해주는 것이다.

 

main함수의 if (mo(s) && mjsequence(s) && sequence(s))에 대해 설명하지면 C/C++은 0은 false, 그 외는 true이다.

C/C++에서는 간결함과 가독성을 위해 if문 안에 ==true, ==1를 명시적으로 쓰지 않아도 된다.

 

'BOJ > string' 카테고리의 다른 글

C++) 17288, 3개만!  (0) 2024.11.23