题目链接:点击打开链接
这个题的trick还是有点的,看点样例吧
/*input
output*/
ace aee a1e //就是出现了歧义就不修改了
ace aee a1e
Apple apple a3e A3E //判断一个字符串是否都是大小写
Apple apple apple APPLE
ABCDEABCDEABCDE a13e A13e //大写的单词能还原小写,而且数字是十位的,不要只当个位处理
ABCDEABCDEABCDE abcdeabcdeabcde Abcdeabcdeabcde
刚开始直接按行读入的,处理起来很麻烦的说,然后再同学那学到了新方法,处理每一个字符,遇到除字符外的题目中提到的符号就进行每个单词的处理
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-8)
#define inf 0x3f3f3f3f
#define ll long long int
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
using namespace std;
const int mod = 1000000007;
const int Max = 100005;
char c;
map<string,string>mp; ///存储 带数字的单词,和此单词的原型
map<string,int>vis; ///存储这个单词的原型有几种情况(如果超过一种情况就不对带数字的单词进行还原)
int fir=1; ///记录是否有第一个单词输入,不然第一次输出会有问题
void skip()///判断特殊符号,遇到的时候直接进行处理,然后跳过
{
while(c=='"'||c=='-'||c==' '||c==','||c=='.'||c=='('||c==')'||c==';'||c==':'||c=='!'||c=='?'||c=='\n')
{
if(!fir)
printf("%c",c);
fir=0;
c=getchar();
}
}
char ans[Max];
int cnt=0;
void get()///存储每一个特殊符号前的单词
{
cnt=0;
while(isalpha(c)||isdigit(c))
{
ans[cnt++]=c;
c=getchar();
}
ans[cnt]='\0';///记得结尾要维护,不然字符串会乱的
}
int main()
{
mp.clear();
vis.clear();
c=' ';
while(c!=EOF)
{
skip();
get();
string tmp,ss;
int sum=0;
if(isdigit(ans[1]))///如果有数字,那么它的第二个字符一定是数字,可以靠这个来判断带数字的单词
{
int len=strlen(ans);
ss=ans;
for(int i=0;i<cnt;i++) ///都将其转化为小写的处理,如果输入中有大写,那么单词还原后之后再考虑大写的还原
{
if(isalpha(ans[i]))
ans[i]=tolower(ans[i]);
}
if(mp.find(ans)!=mp.end()&&vis[ans]==1)///查找前面是否存储过这个单词,vis的意思是没有出现歧义
{
tmp=mp[ans];
int l=tmp.size();
tmp[0]=ss[0]; ///单词的首字母和末尾字母是不用还原的,如果首字母大写,还原后也大写
if(ss[len-1]>='A'&&ss[len-1]<='Z')///如果单词的末字母是大写,那么肯定整个单词都是大写
for(int i=0;i<l;i++)
tmp[i]=toupper(tmp[i]);
cout<<tmp;
}
else
cout<<ss; ///如果不符合情况,直接输出带数字的单词
}
else ///不带数字单词的处理方法
{
printf("%s",ans);
for(int i=0;i<cnt;i++)
if(isalpha(ans[i]))
ans[i]=tolower(ans[i]); ///转化成小写处理并存储
sum=cnt-2; ///将其转化成带数字的格式,判断有没有歧义
ss=ans;
tmp+=ans[0];
string t="";
while(sum)
{
t+=('0'+sum%10);
sum/=10;
}
for(int i=t.size()-1;i>=0;i--)
tmp+=t[i];
tmp+=ans[cnt-1];
if(vis[tmp]==0) ///这是没有存储过的情况,标记为1
vis[tmp]++;
else ///存储过,vis其实存储的是这个带数字单词的还原情况,大于1说明有多种,也就是有歧义
{
if(mp[tmp]!=ss)
vis[tmp]++;
}
mp[tmp]=ss; ///存一下这个单词原型
}
}
return 0;
}