计算字符串中的单词

时间:2014-07-19 13:44:54

标签: c++ string algorithm

我自己学习C ++。我编写了这个程序来计算字符串中的单词数。我知道这不是最好的方法,但这是我能想到的。

我使用空格来计算单词数量。这是问题所在。

countWords("");   // ok, 'x.empty()' identifies it as an empty string.
countWords("  "); // 'x.empty()' fails, function returns 1.

p.s我希望这个程序不计算符号,"!","?"作为文字。这是我的代码:

#include <iostream>
#include <string>

int countWords(std::string x);

int main() {
    std::cout << countWords("Hello world!");
}

int countWords(std::string x) {
    if(x.empty()) return 0; // if the string is empty
    int Num = 1;              

    for(unsigned int i = 0; i < x.size(); i++) {
        // if there is a space in the start
        if(x[0] == ' ') continue;

        // second condition makes sure that i don't count 2 spaces as 2 words
        else if(x[i] == ' ' && x[i - 1] != ' ') Num++;
    }
    return Num;
}

8 个答案:

答案 0 :(得分:2)

你的答案的问题在于,你正在计算出有一个&#39; &#39;标志。我相信你从Num = 1开始,因为你不会计算最后一个字。 Hovewer仅在您分析的字符串不以&#39;结尾时才会发生。 &#39 ;.否则你将再计算1个单词。解决此问题的最简单方法是添加

if(x.back() == ' ')
    Num--;

在回答答案之前。

答案 1 :(得分:1)

您的解决方案不足。应用时会失败:

  • 领先的空间
  • 尾随空格
  • 只有空格
  • 其他形式的空白

您需要重新考虑算法的工作方式,因为您只需要更复杂的方法来涵盖所有用例。

或者您可以避免重新发明轮子并使用标准库已经提供的内容,例如:

int countWords(const std::string& s) {
    std::istringstream iss{s};
    return std::distance(std::istream_iterator<std::string>{iss},
                         std::istream_iterator<std::string>{});
}

此处std::istringstreamstd::istream_iterator用于标记字符串,std::distance用于获取提取的标记数。

答案 2 :(得分:1)

我发现最好使用字符串流:

int Count(const std::string &string)
{
  stringstream ss(string);
  char cmd[256] = {0};
  int Words = 0;
  while(true)
  {
    ss >> cmd;
    if(!ss)
        break;
    Words++;
  }
  return Words;

输入:&#34;亲爱的朋友你好,#34;
输出 4

即使应用于:

也不会失败
  • 领先的空间
  • 尾随空格
  • 只有空格
  • 其他形式的空白

答案 3 :(得分:1)

这在我的机器上简单快捷。它使用bool跟踪字符串 它是否在一个单词内,而空白字符作为单词分隔符。我使用isspace()库函数进行了测试,但此switch语句稍快一些。

int countwords(const std::string &str)
{
    int count = 0;
    bool in_word = false;
    for (char ch : str) {
        switch (ch) {
        case '\t': case '\n': case '\v': case '\f': case '\r': case ' ':
            in_word = false;
            break;
        default:
            if (!in_word) {
                in_word = true;
                ++count;
            }
            break;
        }
    }
    return count;
}

对于不同的单词分隔符,这很容易扩展或修改。这是一个将任何非字母字符视为分隔符的版本。将!isalpha()来电更改为isspace()会产生与上述代码相同的结果。

int countwords(const std::string &str)
{
    int count = 0;
    bool in_word = false;
    for (char ch : str) {
        if (!isalpha(ch)) { // non-alpha chars are word delimiters
            in_word = false;
        } else if (!in_word) {
            in_word = true;
            ++count;
        }
    }
    return count;
}

答案 4 :(得分:1)

您的功能可以简化为:

int countWords(std::string x) {

    int Num = 0;      
    char prev = ' ';

    for(unsigned int i = 0; i < x.size(); i++) {

        if(x[i] != ' ' && prev == ' ') Num++;

        prev = x[i];
    }
    return Num;
}

这是demo

编辑:跟进评论:

这是一种用' '替换其他字符的简单方法,认为可能有这样的构建方法:

void replace(std::string &s, char replacer, std::set<char> &replacies)
{
    for (int i=0; i < s.size(); i++)
        if (replacies.count(s[i])) s[i] = replacer;

}

demo

答案 5 :(得分:0)

int countwords(std::string x)
{
    int i, count = 0;
    for (i = 0; i < x.size(); i++)
        if (x[i] == ' ')
            count++; //just count empty spaces

    count++; //count++ is same as count+1,so there will be count+1 words in string
    if (x.size() == 0)
        count = 0;
    return count;
}

答案 6 :(得分:0)

将以下行添加到代码

int Num;
if(x[0] == ' ') Num = 0;
else Num = 1;

这将消除字符串开头的空白计数

#include <iostream>
#include <string>

int countWords(std::string x);

int main() {
    std::cout << countWords("Hello world!");
}

int countWords(std::string x) {
    if(x.empty()) return 0; // if the string is empty

    int Num;
    if(x[0] == ' ') Num = 0;
    else Num = 1;


    for(unsigned int i = 0; i < x.size(); i++) {
        // if there is a space in the start
        if(x[0] == ' ') continue;

        // second condition makes sure that i don't count 2 spaces as 2 words
        else if(x[i] == ' ' && x[i - 1] != ' ') Num++;
    }
    return Num;
}

答案 7 :(得分:0)

所以在阅读了一些有用的评论后,我自己尝试了。这是我的解决方案。我已经检查了我的程序最糟糕的情况。如果您有任何人,可以找到该程序不起作用的任何案例,请告诉我,以便我可以工作并改进它。

为了清楚起见,我们不想要符号,“,”,“!” ,“?”,“。” ,“\ n”被视为单词。但显然,“我”应该被视为单词,正如我们在语言中所考虑的那样。我通过用空格替换它来确保所有这些。如果我错过了什么,请告诉我。

#include <iostream>
#include <string> 

void replace(std::string& str, char x, char y);
int countWords(std::string x);

int main(){
std::cout<<countWords(" \n \t Hello, world ! ");
}

void replace(std::string& str, char x, char y){
for(unsigned int i=0;i<str.size();i++){
    if(str[i]==x) str[i]=y;
}
}

int countWords(std::string x){

replace(x,',',' ');
replace(x,'.',' ');
replace(x,'!',' ');
replace(x,'?',' ');
replace(x,'(',' ');
replace(x,')',' ');
replace(x,'\n',' ');
replace(x,'\t',' ');
replace(x,'"',' ');

if(x.empty()) return 0;
int Num=1;

for(unsigned int i=1;i<x.size();i++){
    if(x[i]==' ' && x[i-1]!=' ') Num++;
}
if(x.back() == ' ') Num--;
return Num;
}