Algorithms/PS
[PS] 백준 #21966. (중략)
퐁키조아
2022. 1. 27. 09:42
문제 정보
- 난이도: 실버 V
- 문제 주소: https://www.acmicpc.net/problem/21966
- 이 문제를 푼 이유: 그룹 연습 Div.2
문제
드높은 남산 위에 우뚝 선
(중략)
세워라 반석 위에
선린의 터를
1개 이상의 문장들이 주어진다. 아래 규칙에 따라 문장들의 중간 부분을 적당히 생략해 25글자 이내로 요약해서 출력하는 프로그램을 작성하자.
단, 입출력의 편의를 위해 문장들을 공백 없이 모두 붙여 구성한 문자열 S 가 대신 주어진다. 문자열의 첫 글자부터 가장 먼저 만나는 '.'(마침표)까지, 그리고 각 '.'의 다음 글자부터 가장 먼저 만나는 '.'까지를 한 문장으로 생각하기로 하자. 예를 들어 주어진 문자열 가 'IamInevitable.IamIronMan.'이라면 'IamInevitable.'이 한 문장, 'IamIronMan.'이 한 문장이다.
규칙은 다음과 같다.
- 를 그대로 출력한다. 의 길이가 25 이하면
- 의 앞에서부터 11글자, 뒤에서부터 11글자를 제외하고 나머지 부분을 생각하자. 이 나머지 부분이 모두 같은 문장에 속한다면, 생략한 뒤 '...'('.' 3개)으로 바꿔서 출력한다. 의 길이가 25 초과이면,
- 위 두 경우에 해당되지 않는다면 를 앞에서부터 9글자, 뒤에서부터 10글자만 남기고 중간은 '......'('.' 6개)으로 바꿔서 출력한다.
나의 풀이
이 문제는 문자열의 슬라이싱을 활용하는 문제였다. 각 문장들은 문자열 벡터에 . 단위로 끊어서 저장해서 나중에 단어가 문장에 있는지 찾을때 활용한다. n의 값이 25 이하이면 그대로 출력하면 되고, 25 초과면 먼저 문자열의 중간 부분을 잘라서(substr(11, n-11-11)) 각 문장 벡터에서 해당 단어가 존재하는지를 확인한다. 만약 하나라도 존재한다면 '.' 3개로 바꾸고 (2번), 존재하지 않는다면 앞에서부터 9글자, 뒤에서부터 10글자만 남기고 중간은 '......'('.' 6개)으로 바꿔서(3번) 출력한다.
#include <bits/stdc++.h>
using namespace std;
int main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
string str;
vector<string> vec; // Sentences
cin >> n >> str;
string temp;
for (char c : str) {
temp += c;
if (c == '.') { vec.push_back(temp); temp.clear(); continue; }
}
if (n <= 25) { cout << str; return 0; }
else if (n > 25) {
string mid;
mid = str.substr(11, n - 11 - 11);
bool isFind = false;
for (string s : vec) {
if (s.find(mid) != std::string::npos) isFind = true;
}
if (isFind) {
cout << str.substr(0, 11) << "..." << str.substr(n - 11, 11);
}
else {
cout << str.substr(0, 9) << "......" << str.substr(n - 10, 10);
}
}
}