https://www.acmicpc.net/problem/1283
제목 : 단축키 지정
난이도 : Silver II
단축키를 지정하는 조건은 다음과 같아.
- 명령어의 각 단어를 왼쪽부터 차례로 첫 알파벳을 본다.
- 알파벳이 단축키가 지정이 안돼있으면 단축키로 지정하고 넘어간다.
- 지정할 수 없는 단축키면 다음 단어로 넘어간다.
- 단어들의 앞자리가 모두 지정할 수 없는 알파벳이면 전체 명령어를 왼쪽에서부터 보고 단축키를 지정한다.
저는 처음에 공백을 기준으로 명령어를 split 한 다음 각 단어의 앞자리만 확인하여 지정이 돼있는지 안돼있는지 확인했습니다.
대소문자는 구분을 하지 않기 때문에 대문자일 경우엔 소문자로 변환하여 조건을 확인 했습니다.
split된 단어들의 첫 알파벳 모두 지정할 수 없으면 split하기 전의 단어를 가지고 왼쪽부터 탐색하여 조건에 맞으면 단축키로 지정하고 넘어갑니다.
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
vector<string> getsplit(string s) { // 공백을 기준으로 단어 split 하기
stringstream ss(s);
vector<string> tmp;
string t;
while (getline(ss, t, ' ')) {
tmp.push_back(t);
}
return tmp;
}
bool checkbig(char c) { // 대문자 체크
if (c >= 65 && c <= 90) {
return true;
}
return false;
}
string getkey(string s, vector<int> &al) {
bool selected = false;
vector<string> word = getsplit(s);
string tmp = "";
for (int i = 0; i < word.size(); i++) {
// 명령어의 각 단어의 첫 글자를 확인하는 구간.
char a = word[i][0];
if (checkbig(a)) a += 32;
if (!selected && al[a - 'a'] == 0) {
al[a - 'a'] = 1;
string key = "[" + word[i].substr(0, 1) + "]"; // 단어의 맨 앞을 [ ] 로 감싸는 작업.
word[i].replace(0, 1, key);
selected = true;
}
tmp += word[i]; // 탐색을 완료한 각 단어를 하나로 합침.
if (i < word.size() - 1) tmp += " ";
}
s = tmp; // 합친 단어를 기존에 덮어씌우기
if (!selected) { // 만약 단어의 앞자리가 모두 이미 지정된 단축키면 이쪽으로 넘어옴.
for (int i = 0; i < s.length(); i++) {
char a = s[i];
if (checkbig(a)) a += 32;
if (a != ' ' && al[a - 'a'] == 0) {
al[a - 'a'] = 1;
string key = "[" + s.substr(i, 1) + "]";
s.replace(i, 1, key);
break;
}
}
}
return s;
}
int main()
{
vector<int> al(27, 0);
int N;
string s;
vector<string> orders;
cin >> N;
cin.ignore();
for (int i = 0; i < N; i++) {
getline(cin, s);
orders.push_back(s);
}
for (int i = 0; i < N; i++) {
orders[i] = getkey(orders[i], al);
cout << orders[i] << "\n";
}
}
