在介绍这道题之前,先介绍一下紫书里面和这道题很像的一道题:
紫书P112页 的例题5-3 安迪的第一个字典(Andy’s First Dictionary UVa 10815)
原题链接如下:
Andy’s First Dictionary UVa 10815
AC代码如下(解析直接看紫书里的):
#include<iostream>
#include<string>
#include<sstream>
#include<set>
using namespace std;
set<string> dict;
int main(){
string s,buf;
while(cin>>s){
for(int i=0;i<s.size();i++){
if(isalpha(s[i]))
s[i]=tolower(s[i]);
else
s[i]=' ';
}
stringstream ss(s);
while(ss>>buf)
// cout<<buf<<endl;
dict.insert(buf);
}
for(set<string>::iterator it=dict.begin();it!=dict.end();it++){
cout<<*it<<endl;
}
return 0;
}
弄明白上面这题后,对我们今天要AC的这道题就有帮助了。
一开始博主并不觉得有帮助,所以自己一直用暴力的方法去做,发现对于删除字符串中第一个非字母字符时,会把整个字符串删除了。一直得不到满意的解决方法。所以决定网上找题解。可惜只有一篇。用字典树做的。看起来十分复杂。决定自己搞出来。于是就决定用上面这份代码来看看有木有上面帮助。发现还真有。就是神奇的stringstream了。有了这个东西就可以在上面这份代码加上一些这道升级题的特判就可以AC了!
AC代码如下(建议前面看不懂,可以先看后面代码。代码内容相对承上启下,需要通篇看完):
#include<iostream>
#include<string>
#include<sstream>
#include<set>
using namespace std;
set<string> dict;
int main(){
string s,temp,buf;
int flag=0;
while(cin>>s){
for(int i=0;i<s.size();i++){
if(isalpha(s[i])){
s[i]=tolower(s[i]);
if(flag){//判断上一个字符串尾部是否带有‘-’
if(s[s.size()-1]!='-'){//如果当前字符串尾部不带‘-’,说明此单词到这结束了
temp+=s;//和之前的合并
flag=0;//变为0
break;
}else{//否则继续删除尾部“-”,和之前合并。但是该单词还没有结束
s.erase(s.size()-1);
temp+=s;
flag=1;
break;
}
}
}
else if(s[i]=='-'){
if(i==s.size()-1){//如果是尾部‘-’,说明单词还没有结束,需 和下一行第一个字符串合并
s.erase(s.size()-1);//删除“-”
temp=s;
flag=1;//标记该单词还不完整
break;
}else{
temp=s;否则直接赋值给temp
break;
}
}else{
s[i]=' ';//其他字符情况和上一题代码同样处理
}
if(!flag)//这里可以判断单词是否完整,完整就赋值给temp
temp=s;
}
//这里就是和上面代码一样处理了,具体看紫书解释stringstream的用法
if(!flag){
stringstream ss(temp);
while(ss>>buf)
dict.insert(buf);
}
}
//输出
for(set<string>::iterator it=dict.begin();it!=dict.end();it++){
cout<<*it<<endl;
}
return 0;
}