반응형
리뷰
https://www.acmicpc.net/problem/1283
생각보다 생각할게 많은 문자열 구현 문제, 파이썬이면 쉬웠겠지만 C++이라 애좀 먹었다. 그래도 재밌는 문제
전역 변수
- n : 입력되는 문자열의 개수
- v : 알파벳 방문처리를 하기 위한 정수형 배열, 아스키코드 변환이 쉽도록 125크기로 세팅하였다.
함수
1. preprocess
string preprocess(string& str, int index)
단축키 지정이 가능할 경우 단축키에 대괄호를 붙히기 위한 함수
- 대괄호를 붙여야 하는 문자열 str와 대괄호를 붙힐 구간의 index를 매개변수로 입력받아준다.
- front는 str의 begin부터 begin + index까지로 초기화 한다.
- mid는 [ + str의 begin + index부터 begin + index + 1 + ]로 초기화 한다.
- last는 그 이후 문자열을 초기화 해준다.
- front + mid + last를 한 결과 문자열을 return 처리해준다.
문제풀이
- 공백에 대괄호를 씌우지 않게 공백의 아스키코드인 32를 방문처리 해주었다.
- n값을 입력 받고 cin.get()을 진행해 준다, 그래야 다음 getline으로 받을때 줄바꿈을 입력받지 않는다.
- 정답 문자열을 저장할 문자열 벡터 ans를 초기화 해준다.
- n번의 반복문을 실행해 주고, 문자열 변수 temp에 입력 되는 문자열을 한줄로 받아준다.
- stringstream변수 ss에 temp를 지정해 주고, 빈 문자열 s를 초기화 해준다.
- flag를 하나 만들어 주고, ss를 getline하여 공백을 구분으로 temp에 각 문자를 저장해 준다.
- flag가 있고, 각 공백으로 구분한 단어의 앞자리가 방문처리되어있지 않다면
- 방문처리 후 flag = 0으로, preprocess함수에 temp와 0을 매개변수로 전달한다.
- preprocess함수의 리턴값을 temp에 받아주고 s에 temp를 더해준 뒤 뒤에 공백을 추가해 준다.
- 만약 flag가 아직 존재할 경우 단축키 지정에 실패한 경우이므로 2번 조건을 실행해 주어야 한다.
- 문자열을 탐색하며 공백인 경우 continue, 방문처리 되지 않은 문자가 있을 경우 preprocess를 실행해 준다.
- 이번엔 매개변수로 s와 i를 입력해 주어야 하며, 결과값을 s로 받아준다. 이후 break 처리
- ans에 완성된 문자열 s를 push해준다.
- 모든 탐색이 끝나고 ans벡터에 저장된 문자열을 꺼내 공백으로 구분하여 출력해 준다.
참고 사항
- 먼저 하나의 옵션에 대해 왼쪽에서부터 오른쪽 순서로 단어의 첫 글자가 이미 단축키로 지정되었는지 살펴본다. 만약 단축키로 아직 지정이 안 되어있다면 그 알파벳을 단축키로 지정한다.
- 만약 모든 단어의 첫 글자가 이미 지정이 되어있다면 왼쪽에서부터 차례대로 알파벳을 보면서 단축키로 지정 안 된 것이 있다면 단축키로 지정한다.
- 어떠한 것도 단축키로 지정할 수 없다면 그냥 놔두며 대소문자를 구분치 않는다.
- 위의 규칙을 첫 번째 옵션부터 N번째 옵션까지 차례대로 적용한다.
- 1번 조건으로 인해 stringstream을 사용해 공백을 기준으로 각 문자열을 파싱해 왔다.
- 그런데 문제 AC를 맞고 보니 getline을 통해 preprocess를 진행한 경우 break처리를 해주어야 하는 것 같은데 문제가 통과가 되었다, 한 줄에 여러 단어가 주어지는 경우는 없나보다.
- getline으로 한 줄 자체를 받을 경우 만약 이전 입력 인자가 정수였다면 꼭 cin.get()을 해줘야 한다.
- 1, 2번을 구분하기 위해 flag를 사용해 주었다.
- 3번을 구분하기 위해서 tolower를 사용해 주었다.
정답 코드
#include<iostream>
#include<string>
#include<vector>
#include<sstream>
#include<ctype.h>
using namespace std;
int n;
int v[125];
string preprocess(string& str, int index) {
string front = string(str.begin(), str.begin() + index);
string mid = "[" + string(str.begin() + index, str.begin() + index + 1) + "]";
string last = string(str.begin() + index + 1, str.end());
return front + mid + last;
}
int main() {
v[32] = 1;
cin >> n;
cin.get();
vector<string> ans;
for (int i = 0; i < n; i++) {
string temp;
getline(cin, temp);
stringstream ss(temp);
string s = "";
int flag = 1;
while (getline(ss, temp, ' ')) {
if (flag && !v[tolower(temp[0])]) {
v[tolower(temp[0])]++;
flag = 0;
temp = preprocess(temp, 0);
}
s += temp + ' ';
}
if (flag) {
for (int i = 0; i < s.size(); i++) {
if (s[i] == ' ') continue;
if (!v[tolower(s[i])]) {
v[tolower(s[i])]++;
s = preprocess(s, i);
break;
}
}
}
ans.push_back(s);
}
for (string a : ans) cout << a << "\n";
}
728x90
반응형
'알고리즘 공부 > C++' 카테고리의 다른 글
[G5] 백준 14719번 빗물 C++ 구현 (0) | 2024.10.31 |
---|---|
[G5] 백준 20437번 문자열 게임 2 C++ 해시맵, 문자열 (0) | 2024.10.30 |
[S1] 백준 1522번 문자열 교환 C++ 브루트포스 알고리즘, 슬라이딩 윈도우 (0) | 2024.10.29 |
[S1] 백준 2531번 회전 초밥 C++ 슬라이딩 윈도우, 덱 (0) | 2024.10.29 |
[S1] 백준 17615번 볼 모으기 C++ 그리디 알고리즘 (1) | 2024.10.28 |