题意
定义 capitalized word
为首字母大写,后接一个或更多小写字母的单词
定义 abbreviatable sequence of words
为两个或两个以上 capitalized word
的首字母合并序列
对于给定的若干行字符串,将满足条件的 capitalized word
表示为它的缩写,并在其后括号中打印原单词。
解题思路
- 将每行字符串拆分成
单词
和分隔符
。 - 找出其中的
capitalized word
并标记。 - 结合
capitalized word
单词缩写间隔只能为单个空格,写出最长的缩写,并在该段单词前的分隔符中添加缩写 + (
,该段单词后的分隔符中加入)
- 按序打印
单词
和分隔符
。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<fstream>
using namespace std;
string s, word[150], sep[150], up[150];
bool jug(int idx) {
if(word[idx].size() <= 1) return false;
if(word[idx][0] >= 'a' && word[idx][0] <= 'z') return false;
for(int i=1;i<word[idx].size();i++)
if(word[idx][i] >= 'A' && word[idx][i] <= 'Z')
return false;
return true;
}
int main()
{
freopen("abbreviation.in", "r", stdin);
freopen("abbreviation.out", "w", stdout);
while(getline(cin, s))
{
int idw = 0, ids = 0;
sep[0] = "";
for(int i=0;i<s.size();) // 将字符串分割为 `单词` 和 `分隔符`
{
word[++idw] = "";
for(;i<s.size();i++)
{
if(isalpha(s[i]))
word[idw] += s[i];
else break;
}
sep[++ids] = "";
for(;i<s.size();i++)
{
if(!isalpha(s[i]))
sep[ids] += s[i];
else break;
}
}
sep[ids+1] = "";
for(int i=1;i<=idw;i++) // 判断并标记 `capitalized word`
{
if(jug(i)) up[i] = word[i][0];
else up[i] = "";
}
for(int i=1;i<=idw;) // 完成单词缩写
{
if(up[i] != "")
{
string tmp = up[i];
for(int j=i+1;j<=idw;j++)
{
if(sep[j-1] == " " && up[j] != "")
tmp += up[j];
else {
if(tmp.size() >= 2) {
sep[i-1] += tmp + " (",
sep[j-1] = ")" + sep[j-1];
}
i = j;
tmp = "";
break;
}
}
if(tmp != "") {
if(tmp.size() >= 2) {
sep[i-1] += tmp + " (",
sep[idw] = ")" + sep[idw];
}
i = idw+1;
tmp = "";
}
}
else i++;
}
if(sep[0] != "") cout<<sep[0];
for(int i=1;i<idw;i++) //打印结果
cout<<word[i]<<sep[i];
if(sep[idw] == "")
cout<<word[idw]<<endl;
else
cout<<word[idw]<<sep[idw]<<endl;
}
}