문제
https://www.acmicpc.net/problem/1718
1718번: 암호
Vigenere cipher이라는 암호화 방법은 암호화하려는 문장 (평문)의 단어와 암호화 키를 숫자로 바꾼 다음, 평문의 단어에 해당하는 숫자에 암호 키에 해당하는 숫자를 더하는 방식이다. 이 방법을 변
www.acmicpc.net
문제 요약
'암호화 키'와 '평문'이 주어졌을 때, 암호문을 출력한다.
암호문의 i번째 문자는 평문의 i번째 문자를 암호화 키의 i번째 문자의 알파벳 상 순서만큼 앞으로 돌린 문자이다.
+ 암호화 키는 평문의 길이만큼 반복된다.
+ 앞으로 돌렸을 때, 'a'보다 앞의 문자라면, 'z'으로 돌아가 반복된다.
코드
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string str; // 평문
string key; // 암호화 키
vector<char> res;
int main() {
// 공백을 포함한 문자열 입력
getline(cin, str);
getline(cin, key);
// string을 char 배열로 변환
const char* char_arr = str.c_str();
const char* key_arr = key.c_str();
for (int i = 0; i < str.size(); i++) {
// 공백은 그대로 출력
if (char_arr[i] == ' ') {
res.push_back(char_arr[i]);
continue;
}
// 평문의 i번째 문자를 암호화 키의 i번째 문자의 알파벳 상 순서만큼 돌린 문자
char ch = char_arr[i] - (key_arr[i % key.size()] - 'a' + 1);
// 돌렸을 때, 'a'보다 앞의 문자라면 'z'로 돌아가 반복
if (ch < 'a') {
ch += 26;
}
res.push_back(ch);
}
// 결과 출력
for (int i = 0; i < res.size(); i++) {
cout << res[i];
}
}
코드 설명
1. 공백을 포함한 문자열을 입력 받아야 하기 때문에 getline()를 사용한다.
2. 아스키 코드를 이용해서 연산을 하기 위해 c_str()를 이용하여 char 배열로 변환한다.
3. 반복문을 통해 평문과 암호화 키를 앞에서부터 하나씩 접근하여 계산한다.
+ 공백이라면 그대로 출력을 위해 res 벡터에 넣고 continue한다.
key[i % key.size()]
= 암호화 키의 i번째 문자 (평문 길이만큼 반복을 위해 % 사용)
key[i % key.size()] - 'a' + 1
= 암호화 키의 i번째 문자의 알파벳 상 순서
char_arr[i] - key[i % key.size()] - 'a' + 1= 암호화 키의 i번째 문자의 알파벳 상 순서만큼 앞으로 돌린 평문의 i번째 문자
4. 앞으로 돌린 평문의 i번째 문자가 'a'보다 작다면 'z'로 돌아가서 다시 돌린다.
5. 계산한 문자를 벡터에 하나씩 넣고 차례대로 출력한다.
고찰
Python에서 기본기를 익히고 C++로 전환해서 문자열 함수가 아직 익숙하지 않다.
문자열 문제를 조금 더 풀어볼 필요가 있다고 생각한다.
getline(cin, str) : 공백을 포함한 문자열을 string형 str에 저장한다.
str.c_str() : string형 str 문자열을 const char 형 배열로 변환해서 반환한다.
구현의 기본을 꼼꼼히 다시 공부하자.
'Algorithm Problems > 구현' 카테고리의 다른 글
[백준/C++] 4072번: Words (0) | 2024.06.12 |
---|---|
[백준/C++] 4447번: 좋은놈 나쁜놈 (0) | 2024.04.15 |
[백준/C++] 8989번: 시계 (1) | 2024.02.29 |
[백준/Python] 17300번: 패턴 (1) | 2024.01.06 |
[백준/Python] 23349번: 졸업 사진 (0) | 2024.01.01 |