例题5-3安迪的第一个字典 UVa10815--C++STL库映射set的应用

前言

不定期更新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原题:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值