알고리즘 공부/C++

[S1] 백준 1283번 단축키 지정 C++ 구현, 문자열

마달랭 2024. 10. 30. 00:00
반응형

리뷰

 

https://www.acmicpc.net/problem/1283

생각보다 생각할게 많은 문자열 구현 문제, 파이썬이면 쉬웠겠지만 C++이라 애좀 먹었다. 그래도 재밌는 문제

 

전역 변수

  • n : 입력되는 문자열의 개수
  • v : 알파벳 방문처리를 하기 위한 정수형 배열, 아스키코드 변환이 쉽도록 125크기로 세팅하였다.

 

함수

1. preprocess

string preprocess(string& str, int index)

 

단축키 지정이 가능할 경우 단축키에 대괄호를 붙히기 위한 함수

  1. 대괄호를 붙여야 하는 문자열 str와 대괄호를 붙힐 구간의 index를 매개변수로 입력받아준다.
  2. front는 str의 begin부터 begin + index까지로 초기화 한다.
  3. mid는 [ + str의 begin + index부터 begin + index + 1 + ]로 초기화 한다.
  4. last는 그 이후 문자열을 초기화 해준다.
  5. front + mid + last를 한 결과 문자열을 return 처리해준다.

 

문제풀이

  1. 공백에 대괄호를 씌우지 않게 공백의 아스키코드인 32를 방문처리 해주었다.
  2. n값을 입력 받고 cin.get()을 진행해 준다, 그래야 다음 getline으로 받을때 줄바꿈을 입력받지 않는다.
  3. 정답 문자열을 저장할 문자열 벡터 ans를 초기화 해준다.
  4. n번의 반복문을 실행해 주고, 문자열 변수 temp에 입력 되는 문자열을 한줄로 받아준다.
  5. stringstream변수 ss에 temp를 지정해 주고, 빈 문자열 s를 초기화 해준다.
  6. flag를 하나 만들어 주고, ss를 getline하여 공백을 구분으로 temp에 각 문자를 저장해 준다.
  7. flag가 있고, 각 공백으로 구분한 단어의 앞자리가 방문처리되어있지 않다면
  8. 방문처리 후 flag = 0으로, preprocess함수에 temp와 0을 매개변수로 전달한다.
  9. preprocess함수의 리턴값을 temp에 받아주고 s에 temp를 더해준 뒤 뒤에 공백을 추가해 준다.
  10. 만약 flag가 아직 존재할 경우 단축키 지정에 실패한 경우이므로 2번 조건을 실행해 주어야 한다.
  11. 문자열을 탐색하며 공백인 경우 continue, 방문처리 되지 않은 문자가 있을 경우 preprocess를 실행해 준다.
  12. 이번엔 매개변수로 s와 i를 입력해 주어야 하며, 결과값을 s로 받아준다. 이후 break 처리
  13. ans에 완성된 문자열 s를 push해준다.
  14. 모든 탐색이 끝나고 ans벡터에 저장된 문자열을 꺼내 공백으로 구분하여 출력해 준다.

 

참고 사항

  1. 먼저 하나의 옵션에 대해 왼쪽에서부터 오른쪽 순서로 단어의 첫 글자가 이미 단축키로 지정되었는지 살펴본다. 만약 단축키로 아직 지정이 안 되어있다면 그 알파벳을 단축키로 지정한다.
  2. 만약 모든 단어의 첫 글자가 이미 지정이 되어있다면 왼쪽에서부터 차례대로 알파벳을 보면서 단축키로 지정 안 된 것이 있다면 단축키로 지정한다.
  3. 어떠한 것도 단축키로 지정할 수 없다면 그냥 놔두며 대소문자를 구분치 않는다.
  4. 위의 규칙을 첫 번째 옵션부터 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
반응형