Gi-Log

백준(BOJ) 4446 ROT13 C++ 풀이 본문

알고리즘 BOJ

백준(BOJ) 4446 ROT13 C++ 풀이

돌잔 2021. 7. 18. 19:41

문제 링크: https://www.acmicpc.net/problem/4446

 

4446번: ROT13

간달프는 여러 종족의 언어를 꽤 오랜 시간 동안 공부했다. 최근에 간달프는 해커들이 사용하는 언어인 ROT13을 공부했다. 이 언어는 영어와 문법이 같지만, 알파벳의 순서를 어떤 규칙을 이용해

www.acmicpc.net

문제 풀이에 이용된 알고리즘: 구현

 

문제에서 원하는 조건들을 단순히 구현하면 되는 문제이다.

 

구현을 하는 방법은 다양하게 있으므로, 무엇이 정답이다!라고 말하기에는 적절하지 않은 것 같다.

 

다만, 이번 문제처럼 입력 받은 어떤 데이터들을 "사이클"로 만드는 경우에는, 입력 데이터를 두번 이상 반복해서 입력 받는 것이 좋다.

 

예를 들어, a i y e o u에서 e로부터 오른쪽 세번째는 a라는 것이 자명한데, 이를 코드로 구현하기 위해서는 다음과 같이  구현이 가능하다.

 

a의 인덱스 i를 1이라고 할 때, e의 인덱스 i는 4이며, 우측 세번째에 존재하는 글자의 인덱스 i는 4 + 3 = 7이 될 것이다. 가장 큰 인덱스가 i = 6이므로, 7번째 인덱스는 실제로 존재하지 않고 7 - 6 = 1번째 인덱스인 a가 정답이 되는 것이다.

 

위처럼 - 연산으로 구할 수도 있지만, 개인적으로는 입력 시퀀스를 a i y e o u a i y e o u로 만들어서 7번째 인덱스의 문자를 만들어주는 편이다. 또는 모듈러 연산으로도 구현할 수 있다. (이 경우, 좌측으로 이동할 때에 대해서는 음의 인덱스가 발생할 수 있으므로 모듈러 연산하기 전에 전체 데이터의 개수를 합해주는 단순하지만 누군가에게는 충분히 생소할 수 있는 별도의 사고 과정이 필요하다...)

 

그리고 대문자냐, 소문자냐, 알파벳이냐 등등을 아스키 코드 값 범위를 이용한 if문으로 파악할 수도 있지만, isupper, islower, isalpha(알파벳이 아니면 0, 대문자면 1, 소문자면 2 return) 등의 다양한 함수를 이용하면 훨씬 쉽고, 실수 없이 구현할 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* BOJ 4446 ROT13 */
#define _CRT_SECURE_NO_WARNINGS
 
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <string.h>
 
#define endl '\n'
 
using namespace std;
 
typedef long long ll;
 
string str;
char vowel[12= { 'a''i''y''e''o''u''a''i''y''e''o''u' };
char consonant[40= { 'b','k','x','z','n','h','d','c','w','g','p','v','j','q','t','s','r','l','m','f'
                    , 'b','k','x','z','n','h','d','c','w','g','p','v','j','q','t','s','r','l','m','f' };
 
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
    freopen("input.txt""r", stdin);
 
    while (getline(cin, str))
    {
        for (int i = 0; i < str.length(); i++)
        {
            if (isalpha(str[i]) == 0)
                continue;
 
            bool is_upper = false;
            // 대, 소문자 확인
            if (isupper(str[i]))
            {
                is_upper = true;
                str[i] = tolower(str[i]);
            }
 
            bool is_vowel = false;
            if (str[i] == 'a' || str[i] == 'i' || str[i] == 'y' || str[i] == 'e' || str[i] == 'o' || str[i] == 'u')
                is_vowel = true;
 
            if (is_vowel) // str[i]가 모음인 경우
            {
                for (int j = 6; j < 12; j++)
                {
                    if (str[i] == vowel[j])
                    {
                        str[i] = vowel[j - 3];
                        break;
                    }
                }
            }
            else // str[i]가 자음인 경우
            {
                for (int j = 20; j < 40; j++)
                {
                    if (str[i] == consonant[j])
                    {
                        str[i] = consonant[j - 10];
                        break;
                    }
                }
            }
 
            if (is_upper) // 원래 대문자 였던 경우
                str[i] = toupper(str[i]);
        }
 
        cout << str << endl;
    }
 
    return 0;
}
 
cs

 

Comments