内容
8岁的Andy有一个梦想——创作自己的字典。对他来说,这不是一个容易的任务。他所知道的单词还不够多。他不是自己思考,而是有一个绝妙的想法。从他的书架挑选最爱的故事书,复制所有不同的单词。通过按字典序排列,他居然完成了。当然,这是一个十分耗时的工作,不过有计算机的帮助。
请求你写一个程序列出输入文本中所有不同的单词。在这个问题里,一个单词背定义为包含大小写的连续的字母。一个字母也被认为是一个单词。此外,你的程序不应该区分字母的大小写。比如,“Apple”、“apple”、“APPLE”被认为是同一个单词。
输入
输入文件是一个不超过5000行的文本。一行最多200个字符。以“EOF”为终止标志。
输出
你的输出应该给出在输入中出现的所有不同的单词,一个单词占一行。按全部字母小写并且单词按字典序输出。你可以确定的是,输入文本中不同的单词不会超过5000个。
想法
- 题目要求输出所有的不同的单词,想到集合有这样的性质:每个元素都是唯一的。
- 不区分大小写,那么所有的单词应该标准化(大写字母转换为小写字母且标点符号转换为空白符)。
代码
#include <iostream>
#include <string>
#include <set>
#include <sstream>
#include <fstream>
using namespace std;
//#define yydebug
set<string> setWords;
int main(int argc, char **argv)
{
#ifdef yydebug
ifstream cin("in.txt");
ofstream cout("out.txt");
#endif
string s, buf;
while (cin >> s)
{
for (int i = 0; i < s.length(); i++)
isalpha(s[i]) ? s[i] = tolower(s[i]) : s[i] = ' ';
stringstream ss(s);
while (ss >> buf)
setWords.insert(buf);
}
for (set<string>::iterator it = setWords.begin(); it != setWords.end(); ++it)
{
cout << *it << endl;
}
return 0;
}
看到网上许多博客里将定义一个ifstream对象cin、一个ofstream对象cout称作c++标准输入输出流的重定向。简直是大谬!根本就不是什么所谓的重定向。只是在main()函数里的局部变量cin\cout覆盖了std::cin/std::cout而已(思考变量的生命周期以及全局变量和局部变量同名时的情况)。切记,只是变量名相同,根本就不是类似C语言里这样的重定向:
#ifdef yydebug
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
将宏定义yydebug注释掉之后,cin/cout就是istream和ostream的对象了。可以把这种方法称之为掩耳盗铃。这道题简单地利用C++STL中的set的性质即可解之。