C++ Primer 9.39
已知有如下string对象:
string line1 = "We were her pride of 10 she named us:";
string line2 = "Benjamin, Phoenix, the Prodigal";
string line3 = "and perspicacious pacific Suzanne";
string sentence = line1 + ' ' + line2 + ' ' + line3;
编写程序计算sentence中有多少个单词,并指出其中最长和最短的单词。如果有多个最长或最短的单词,则将它们全部输出。
想法:
1、将string sentence对象转换为vector<string> s对象,利用vector<string>的方法实现对单词个数的统计、寻找最长或最短的单词。
2、提取sentence中的单词,利用的是空格分隔符。sentence.find_first_of(gap,pos)函数寻找到空格符后返回sentence中空格第一次出现的位置pos。
3、因为sentence中有非字母字符,尝试着在将string sentence中的单词写入vector<string> s前,先剔除掉这些非字母字符。这里利用了string类的对字符的操作方法isalpha(c)判断字符,同时利用length来计算字母个数。用substr(beg,length)来提取字串,写入vector<string> s中。
4、对vector<string> s进行遍历,找出最长或最短的单词长度分别记入为max、min。
5、对vector<string> s进行遍历,依据max、min做为输出单词的判断条件,同时用s.size()输出sentence中单词的个数。
源码:
#include "cpp.h"
int main(){
string line1 = "We were her pride of 10 she named us:";
string line2 = "Benjamin, Phoenix, the Prodigal";
string line3 = "and perspicacious pacific Suzanne";
string sentence = line1 + ' ' + line2 + ' ' + line3;
string gap(" ");
string::size_type pos = 0;
string::size_type beg = 0;
string::size_type length = 0;
vector<string> s;
while((pos = sentence.find_first_of(gap,pos)) != string::npos)
{
for(string::size_type i=beg; i != pos;i++)
{
if(isalpha(sentence[i]))
{
length++;
}
}
if(length == 0)
{
beg = ++pos;
continue;
}
else
{
s.push_back(sentence.substr(beg,length));
beg = ++pos;
length = 0;
}
}
s.push_back(sentence.substr(beg));
int max=0;
int min=0;
for(vector<string>::iterator idex=s.begin();idex != s.end();idex++)
{
max = (max <= (*idex).size() ? (*idex).size():max);
min = (min >= (*idex).size() ? min:(*idex).size());
}
for(vector<string>::iterator idex=s.begin();idex != s.end();idex++)
{
if((*idex).size() == max)
cout << "The longest word: " << *idex << " ";
}
cout << endl;
for(vector<string>::iterator idex=s.begin();idex != s.end();idex++)
{
if((*idex).size() == min)
cout << "The shortest word: " << *idex << " ";
}
cout << endl;
cout << "sentence have " << s.size() << " words" << endl;
return 0;
}
思考:
参考了其他实现方法,发现有些想法特别好。在提取提取单词时,可以同过end=sentence.find_first_of(,pos)来找到一个字串的末尾的后一个字符位置,通过pos=sentence.find_fisrt_not_of(,pos)来找到字串的开始位置。同时用两个vector<string>来记录最长的单词和最短的单词,并且在一个循环中实现从sentence到两个vector<string>转换。我的实现方法循环遍历多了一轮,感觉对很长的字符串做处理会非常消耗时间。