前言
不定期更新C++的STL库以及算法练习的笔记 分享给大家 也是督促自己不断努力学习算法与程序设计 学习算法之前,要想高效简洁的写好代码,还需要熟练掌握STL库的一些方法和数据结构 参考书籍: 《算法竞赛入门经典》(第2版)刘汝佳 著 《挑战程序设计竞赛》巫泽俊 主译
一、题目描述
输入一个文本,找出所有不同的单词(连续的字母序列),按字典序从小到大输出。单词不区分大小写。 Sample Input Adventures in Disneyland Two blondes were going to Disneyland when they came to a fork in the road. The sign read: “Disneyland Left.” So they went home. Sample Output a adventures blondes came disneyland fork going home in left read road sign so the they to two went were when 注:文末附有原版英文题目
二、思路分析与代码书写
1.集合set
题目中提到“所有不同的单词”,一下子就能想到集合,因为集合具有互异性【任意一个元素不会在集合中出现多次】 此外,STL中的集合还默认将元素从小到大排列,这样还解决了字典序的问题。 综上,基于互异性和字典序,我们选择创建集合来解题。 如果对set的使用不熟练,或者第一次接触,可以看这一篇文章: C++STL集合set基本使用
2.题目思路分析
①单词不区分大小写,显然我们需要有一个将单词统一成小写(因为小写字母占绝大多数)的过程。 ②此外,样例输入的文本中有句点.也需要处理,否则影响我们程序的搭建。这里将句点统一换成空格(因为单词之间本身就是空格隔开)。 ③一段文字可以是一个string。但显然我们希望一个单词是一个string。既然输入的是一段文本,也就是单词和空格的组合,那这时我们想到用stringstream流读入读出,也就是说从流里每次读出一个string并加入集合。显然如果这个单词已经出现过了,集合里不会重复添加。 ④最后定义一个迭代器iterator,用以遍历集合中所有的单词并输出。
3.完整代码书写
该代码参考刘汝佳老师书上的代码,自己根据思路独立完成,可能细节上与老师略有不同。
首先是头文件,一个都不能少。(实际写代码过程中可能是边写边添加的)
#include<iostream>
#include<set>
#include<string>
#include<sstream>
#include<cctype>
其中cctype提供tolower()函数和isalpha()函数
考虑到文段中有字母空格和句点三种情况,因此分两类处理: 是字母的,变小写 否则,变空格
完整程序:
int main()
{
string s,buf;
while(cin>>s){
if(s[0]=='#')break;
for(int i=0;i<s.length();i++){
if(isalpha(s[i]))s[i]=tolower(s[i]);
else s[i]=' ';
}
stringstream ss(s);
while(ss>>buf)dict.insert(buf);
}
set<string>::iterator it;
for(it=dict.begin();it!=dict.end();++it){
cout<<*it<<endl;
}
return 0;
}
最后几句话
集合有着其互异性这一独特的特性,因此在许多竞赛和练习中应用广泛。 使用时务必记得头文件#include<set> 另外string和stringstream虽然好用。但是在算法竞赛中依然要慎重。因为string慢,stringstream更慢。 附:UVa10815原题:
|