设为首页 加入收藏

TOP

8.8.5 搜索字符串(3)
2013-10-07 12:37:42 来源: 作者: 【 】 浏览:66
Tags:8.8.5 搜索 字符串

8.8.5  搜索字符串(3)

下面是该程序的部分输出:

  1. Enter some text on as many lines as you wish.  
  2. Terminate the input with an asterisk:  
  3. I sometimes think I'd rather crow  
  4. And be a rooster that to roost  
  5. And be a crow. But I dunno.  
  6.  
  7. A rooster he can roost also,  
  8. Which don't seem fair when crows can't crow  
  9. Which may help some. Still I dunno.*  
  10.  
  11. In ascending sequence, the words in the text are: 

A < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

1

And

2

But

1

I

3

I'd

1

Still

1

Which

2

a

2

also

1

be

2

can

1

can't

1

crow

3

crows

1

don't

1

dunno

2

fair

1

he

1

help

1

may

1

rather

1

roost

2

rooster

2

seem

1

some

1

sometimes

1

that

1

think

1

to

1

when

1

示例说明

在本示例中使用getline()从cin中读取输入,终止字符被指定为一个星号。这样允许输入任意行代码。单个单词从对字符串对象text的输入中提取出来,并存储在words数组中。这是通过while循环完成的。

从text中提取单词的第一步是找到单词的第一个字符的索引位置:

  1. start = text.find_first_not_of(separators,
    offset); // Find non-separator  
  2. if(start == string::npos) // If we did not find it, we are done  
  3. break;  
  4. offset = start + 1;         // Move past character found 

调用find_first_not_of()函数返回位置offset中第一个不是separators中的字符之一的字符的索引位置。这里我们可以用find_first_of()函数来搜索A~Z,a~z中的任何字符来得到同样的结果。当提取了最后一个单词后,搜索会到达字符串的末尾,而没有发现任何匹配的字符,因此我们通过将返回的值与string::npos作比较来进行测试。如果它是字符串的末尾,就提取所有单词,因此我们退出循环。在任何其他情况下,我们就在发现的字符后面一个字符处设置offset。

下一步是搜索任何分隔符字符:

  1. end = text.find_first_of(separators,offset); // Find separator  
  2. if(end == string::npos)             // If it's the end of the string  
  3. {           // current word is last in string  
  4. offset = end;   // We use offset to end loop later  
  5. end = text.length();            // Set end as 1 past last character  
  6. }  
  7. else  
  8. offset = end + 1;  
  9.     // Move past character found 

这段代码从索引位置offset处搜索任何分隔符,这是单词的第一个字符后面的字符,因此通常我们会发现分隔符是单词的最后一个字符后面的字符。当单词是文本中的最后一个词,而且该单词的最后一个字符后面没有分隔符时,函数就会返回string::npos,因此我们这样处理此类情况:将end设置为字符串中最后一个字符后面的字符,并将offset设置为string::npos。以后在提取当前单词之后的循环中会测试offset变量来判断是否应结束循环。

单词的提取并不难:

  1. words[nwords] = text.substr(start, end-start);  
    // Extract the word 

substr()函数在text中从strart处的字符开始提取end-start个字符。单词的长度是end-start,因为start是第一个字符,而end是单词中的最后一个字符后面的那个字符。

while循环体的其余部分以前面介绍的方式跟踪最大单词长度,检查字符串结束条件,并检查words数组有没有满。

这些单词在一个for循环中输出,它们在words数组中的所有元素上迭代。循环中的if语句用来计数重复的单词:

  1. if(count == 0)  
  2. count = 1;  
  3. if(i < nwords-2 && words[i] == words[i+1])  
  4. {  
  5. ++count;  
  6. continue;  

count变量记录重复的单词个数,因此它的最小值总是为1。在循环的末尾,当一个单词和它的个数被写出后,count被设置为0。它充当一个指示器,表示新的单词计数开始了,因此当count为0时,第一个if语句将它设置为1,否则它就会保留为当前值。

第二个if语句检查下一个单词与当前单词是否相同,如果相同,则count递增,并跳过当前循环迭代的其余部分。该机制用count累计单词的重复次数。循环条件也检查索引i是否小于nwords-2,若当前单词是数组中的最后一个单词,我们就不用检查下一个单词。因此,当下一个单词与当前单词不同,或者当前单词是数组中的最后一个单词时,我们仅输出一个单词和它的计数。

for循环中的最后一步是输出一个单词和它的计数:

  1. cout << setiosflags(ios::left)  // Output word left-justified  
  2. << setw(maxwidth+2) << words[i];  
  3. cout << resetiosflags(ios::right)       // and word count right-justified  
  4. << setw(5) << count << endl;  
  5. count = 0
该输出语句将单词在比最长单词长两个字符的字段宽度中左对齐。计数输出是在宽度为5的字段宽度中右对齐。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇8.8.1 创建字符串对象 下一篇8.8.5 搜索字符串(2)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: