【问题标题】:Counting words in a string in C在C中计算字符串中的单词
【发布时间】:2020-08-08 22:29:22
【问题描述】:

我写了一段代码来计算一个字符串包含多少个单词。

我已经尝试了多个输入,并且大多数输入都是正确的,但有些情况表明我的程序存在基本的逻辑缺陷。例如,如果我在一个空字符串中设置,输出将错误地为 1,如果我在字符串的末尾添加空格,由于某种原因,我不知道输出将是 1+其中的实际单词数字符串和我的代码显然表明我想取出所有空格/制表符。

我的程序基本上是在一个字符串中这样做的,但不幸的是没有在它的末尾。我很清楚我的功能有问题,但我不知道是什么。而且我知道借助外部库可能更容易实现它,但我被要求用纯基本代码来实现它。

这是我目前所拥有的:

int get_number_of_words(char input_string[])
{
    int i, j, counter = 0;
    for (i = 0; i < STRING_SIZE; i++)
    {
        if (input_string[i] != ' ')
        {
            counter++;
            j = i;
            while ((input_string[j] != ' '))
                j++;
            i = j;
        }
    }
    return counter;
}

我会给你一些输入和输出字符串的例子:

  • "Hello\t\t\t" - 1 个字(标签被忽略)
  • "Hello" - 1 个字
  • "" - 0 字
  • "\t\tThis is a basic example\t\t\t" - 5 个字(忽略标签)
  • "This is a basic example " - 5 个单词(最后一个空格被忽略)

稍后,我将不得不考虑不同的标点符号(包含在单词中),但与此同时,我只想掌握程序的核心。

【问题讨论】:

  • 你能包含一些输入字符串和(预期的)输出吗?问题描述很清楚,但我不确定例如当前代码中的制表符、换行符和问题。输入输出将极大地阐明这些。
  • 出现在末尾或开头的空格,换行符或制表符等空格字符是有问题的。这些字符可以连续出现,也可以出现在字母数字字符之间。此外,这些字符可能取决于操作系统
  • 越界访问的未定义行为。
  • 如果您有两个空格,您的程序将计算两个单词,您可以尝试使用 int 作为 bool 来控制它
  • 如果input_string 指向一个字符串字面量或char 数组小于SIZE_STRING 怎么办?然后,您的未定义行为读取超出了引用的 char 数组或字符串文字的范围。

标签: c string word-count


【解决方案1】:

如果你只是在寻找一个可行的算法,这里是逻辑:

  1. 使用空格分隔/拆分句子/(字串)。结果将是一个数组。
  2. 过滤数组以删除任何空白字符串(空格)、不需要的单词,例如 'is' 'a' 'an'。
  3. 计算结果数组的长度。

这应该是你的答案。希望你能把指令转换成程序。

【讨论】:

    【解决方案2】:

    这是修改后的代码。请参考 cmets 以获得更好的理解。我还假设 STRING_SIZE 会大于输入字符串的长度。

    int get_number_of_words(char input_string[])
    {
        int i, j, counter = 0;
        for (i = 0; i < STRING_SIZE; i++)
        {
            // This makes sure that when the 'i' in input_string is reached to end,
            // you must not check further. It is basically last char of string.
            if(input_string[i]=='\0')break;
    
            // only enter this if condition if encounter a char a-z or A-Z
            if((input_string[i]>='A'&&input_string[i]<='Z')||(input_string[i]>='a'&&input_string[i]<='z'))
            {
                counter++;
                j = i;
                // if there is no ' ' then this loop will run forever.
                // thus added a constraint. 
                // iterate this loop till you read char from a-z or A-Z
                while (j<STRING_SIZE && ((input_string[j]>='A'&&input_string[j]<='Z')||(input_string[j]>='a'&&input_string[j]<='z')))
                    j++;
                i = j;
            }
    
        }
        return counter;
    }
    

    【讨论】:

    • 此代码适用于您的所有示例测试用例。并且还为我自己的测试用例运行。
    【解决方案3】:

    使用如下循环:

    for (i = 0; i < STRING_SIZE; i++)
    

    似乎是个坏主意。我假设 STRING_SIZE 是在#define 中设置的某个固定数字,它不起作用,因为输入字符串可以更短也可以更长。

    相反,我建议您使用指针来迭代字符串,即将指针初始化为指向字符串的开头,并在每个循环中递增指针并继续循环,直到您看到字符串终止。

    可能看起来像:

    #include <stdio.h>
    
    int is_whitespace(char c)
    {
        // Check for space or tab
        return (c == ' ' || c == '\t');
    }
    
    int get_number_of_words(char* input_string)
    {
        int counter = 0;
    
        // Make p point to start of string
        char* p = input_string;
    
        // Remove whitespaces, i.e. look for next word or end-of-string
        while (*p && is_whitespace(*p)) ++p;
    
        while(*p)
        {
            ++counter;
    
            // Continue down the string until a whitespace or end-of-string is found
            while(*p && !is_whitespace(*p)) ++p;
    
            // Remove whitespaces, i.e. look for next word or end-of-string
            while (*p && is_whitespace(*p)) ++p;
        }
        return counter;
    }
    
    
    int main()
    {
        char* str1 = "some text";
        printf("%s %d\n", str1, get_number_of_words(str1));
        char* str2 = "         some                   text                  ";
        printf("%s %d\n", str2, get_number_of_words(str2));
        char* str3 = "some\ttext";
        printf("%s %d\n", str3, get_number_of_words(str3));
        char* str4 = "\tsome\t\ttext\t\t";
        printf("%s %d\n", str4, get_number_of_words(str4));
        return 0;
    }
    

    输出:

    some text 2
             some                   text                   2
    some    text 2
        some        text         2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-23
      • 2023-03-21
      • 2013-07-22
      • 2012-10-04
      相关资源
      最近更新 更多