문제
키보드 레이아웃에서 한 칸 오른쪽으로 밀려서 입력된 문자열을 원래 문자로 복원하는 문제다. 각 문자를 키보드 행에서 왼쪽으로 한 칸 이동한 문자로 치환하면 된다. 공백은 그대로 유지한다.
입력
- 여러 줄의 문자열이 주어지며, EOF까지 읽는다.
출력
- 각 문자를 키보드에서 왼쪽으로 한 칸 이동한 문자로 변환하여 출력한다.
예제
| 입력 | 출력 |
|---|---|
eua/ | was. |
trww p[ | stop it |
풀이
키보드 4개 행의 문자열을 미리 정의해두고, 입력 문자의 위치를 찾아 왼쪽 한 칸의 문자로 치환한다.
- 키보드 4행을 문자열 배열로 미리 정의:
`1234567890-=등 - 각 문자에 대해 공백이면 그대로 출력
- 공백이 아니면 4개 행에서 해당 문자의 위치
(i, j)탐색 - 찾은 위치에서
str[i][j-1]을 출력 (왼쪽 한 칸) - 한 줄이 끝나면 줄바꿈 출력
핵심 아이디어: 키보드 각 행의 첫 번째 문자는 왼쪽으로 밀 수 없으므로, 입력에서 각 행의 두 번째 문자부터 등장한다고 가정한다. j-1 인덱스 접근이 유효한 것은 이 전제 덕분이다.
코드
#include <iostream>
#include <string>
using namespace std;
string str[4] = {
"`1234567890-=",
"QWERTYUIOP[]\\",
"ASDFGHJKL;'",
"ZXCVBNM,./"};
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
string s;
while (getline(cin, s))
{
for (int t = 0; t < s.size(); t++)
{
if (s[t] == ' ')
{
cout << s[t];
continue;
}
bool found = false;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < str[i].size(); j++)
{
if (s[t] == str[i][j])
{
cout << str[i][j - 1];
found = true;
break;
}
}
if (found)
break;
}
}
cout << '\n';
}
return 0;
}복잡도
- 시간: O(N * L) — 문자열 수 N, 각 행의 길이 L(최대 13)
- 공간: O(L) — 키보드 행 문자열 고정 저장