杭电OJ 字符串类题目解题思路

Posted on 2020-09-23 22:18  ZOMIN28  阅读(229)  评论(0编辑  收藏  举报

一、前言

笔者将按照题目的类型进行博客的发表,仅供学习、交流和参考。

 

二、题解

2072、单词数

此题的思路很简单,我们接收一个字符串,将其中的单词逐个提取出来;然后构造一个结构存储单词字符串,此结构初始时为空,每次将逐个取出的单词与此结构中的所有单词比较,如果此单词已经存储,继续提取下一个单词;如果还未存储,那么存储此单词在结构中,单词计数器加一。

此题有以下几个需要注意的地方:

1、输入字符串的接收。如果我们仅使用cin来输入字符串,那么遇到空格时,一次输入就会结束,无法接收完整的字符串。故在此题中需要使用以下:

getline(cin,string s),可以输入时接收空格在字符串中,遇到回车符结束一次输入。包含在<string>头文件中。
 
2、存储结构的选则。因为我们一开始不知道一句话会有多少个单词,也不知道单词数的上限,所以选择可变长结构vector来存储字符串。因此,我们在最后计算单词个数时,既可以使用自定义的计数器count,也可以直接使用函数vector.size()。
 
3、此题可能会出现在句子开头、结尾出现空格以及两个单词中间出现多个空格的情况,要在程序中予以考虑。
 
笔者源代码如下:
#include<iostream>
#include<vector>
#include<string.h>
#include<string>
using namespace std;

int main(void){
    string s;
    while(getline(cin,s)){
        int count = 0;
        if(s=="#") break;
        vector<string>vec;   //用于存放已经统计过的字符串
        int len = s.length();
        int begin = 0;       //本次截取的头部
        for(int i=0;i<len;i++){
            if(s[i]==' '||i==len-1){
                string now;
                if(s[i]==' ') now = s.substr(begin,i-begin);
                else if(i==len-1) now = s.substr(begin,len-begin);
                int j;
                for(j=0;j<count;j++){
                    if(now==vec[j]) break;
                }
                if(j==count&&now!=""){    //防止开头、结尾有空格同时中间有多个空格的情况
                    vec.push_back(now);   //如果这个单词还没有被统计过,则放入容器中
                    count++;
                }
                begin = i + 1;  //更新截取起始位置
            }
            
        }
        cout<<count<<endl;
        vec.clear();
    }
    return 0;
}