繁体   English   中英

计算具有多个空格的字符串中的单词

[英]Count words from a string with multiple empty spaces

我需要的代码可以计算字符串中的单词,而无需计算它们之间的多个空格。

我可以编写一个程序来计算单词,单词之间只有1个空格,但是当它超过1个空格时,我不知道如何编码。 我想到了类似for循环的功能,它可以检查char之前是否为空格,但是我不知道该怎么做。 我想提到我是C语言的初学者。

#include <stdio.h>
#include <string.h>

int main()
{
char s[200];
int count = 0, i;

printf("enter the string: ");
fgets(s,200,stdin);
for (i = 0;s[i] != '\0';i++)
{
    if (s[i] == ' ')
        count++;    
}
printf("number of words in given string are: %d\n", count+ 1);

return(0);
} 

您可以引入一个标志来告诉前一个字符是否为空格。 就像是:

#include <stdio.h>
#include <string.h>

int main()
{
    char s[200];
    int count = 0, i;
    int last_was_space = 1;

    printf("enter the string: ");
    fgets(s,200,stdin);
    for (i = 0;s[i] != '\0';i++)
    {
        if (s[i] == ' ')
        {
            if (!last_was_space) 
            {
                count++; // Only count when last char wasn't a space
                last_was_space = 1;
            }
        }
        else
        {
            // Update flag (unless this char is a newline)
            if (s[i] != '\n') last_was_space = 0;
        }
    }
    if (!last_was_space) ++count; // Count the last word if there wasn't a space before

    printf("number of words in given string are: %d\n", count);

    return(0);
}

通用一点

size_t wcount(const char *s, const char *del, int countempty)
{
   char *token;
   size_t count = 0;
   char *str = strdup(s);

   if(str)
   {
        token = strtok(str, del);
        while( token != NULL ) 
        {
          if(!strlen(token))
          {
              if(countempty)
              {
                  count++;
              }
          }
          else
          {
              count++;
          }
          token = strtok(NULL, del);
        }
   }
   free(str);
   return count;
}

int main () 
{
    char str[] = "something to   count    ,., , . !! Stack    overflow  ";

    printf("With empty %zu, Without empty%zu\n", wcount(str," ", 1), wcount(str," .,", 0));
}

概括地说,解决这个问题很有帮助。 不要将其视为“计数单词”或“计数空格”。 可以将其视为计数“从分隔符到非分隔符的转换”。 定义我们的条款:

  • 分隔符:字符串的开头,或单个ASCII空间
  • 非分隔符:其他所有内容

示例(^是字符串的开头,_是文字空间,$是字符串的结尾):

^a_quick_brown_fox_jumps$
 ^ ^     ^     ^   ^               5 transitions

^_a__quick___brownfox_jumps___$
  ^  ^       ^        ^            4 transitions

^$
                                   0 transitions

^___$
                                   0 transitions

^__x$
   ^                               1 transition

现在在伪代码中:

def is_separator(char x):
  return (x == NULL or x == ' ')

def is_non_separator(char x):
  return (! is_separator(x))

let count = 0, last_char = NULL
while current_char = read_char():
  if (is_non_separator(current_char) and is_separator(last_char)):
    count++

在这里,您可以翻译成特定的语言或更改分隔符的含义,而不会影响计数的逻辑。

计算字符串中的单词,但不计算单词之间的多个空格

设置一个标志来确定单词的开头是否可能。 比寻找单词的结尾少的特殊情况。

通常,对“空格”的要求包含任何空格,然后可以轻松地对任务进行编码:

#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

int main(void) {
  char s[200];
  printf("enter the string: ");
  fgets(s, sizeof s, stdin);

  int count = 0;
  bool beginning_of_word_possible = true;

  for (const char *p = s; *p; p++) {
    if (isspace((unsigned char ) *p)) {
      beginning_of_word_possible = true;
    } else {
      if (beginning_of_word_possible) {
        count++;
      }
      beginning_of_word_possible = false;
    }
  }

  printf("number of words in given string are: %d\n", count);
  return (0);
}

@P__J__提供了一个很好的主意,该主意可以传入定界符列表。 下面是一个相似且简短的解决方案,它既不分配内存也不更改提供的字符串。

#include <string.h>

size_t word_count(const char *s, const char *delimiters) {
  size_t count = 0;
  while (*(s += strspn(s, delimiters))) {  // Advance s by the matching delimiters.
    count++;
    s += strcspn(s, delimiters);           // Advance s by the non-matching delimiters.
  }
  return count;
}

测试

int main(void) {
  const char *de = " \n";
  printf("%zu\n", word_count("", de));
  printf("%zu\n", word_count("\n", de));
  printf("%zu\n", word_count("  ", de));
  printf("%zu\n", word_count("abc", de));
  printf("%zu\n", word_count(" abc", de));
  printf("%zu\n", word_count(" abc \n", de));
  printf("%zu\n", word_count("abc xyz", de));
  printf("%zu\n", word_count(" abc  xyz", de));
  printf("%zu\n", word_count(" abc  xyz  \n", de));
}

产量

0
0
0
1
1
1
2
2
2

简短版本:

#include <stdio.h>

int main(void) {
    char str[] = "  Hello, This is   a test  of a word     counter";
    int i = 0;
    for(char* s=str; strtok(s," "); i++) s = NULL;
    printf("number of words in given string are: %d\n", i);
    return 0;
}

产量

Success #stdin #stdout 0s 9424KB
number of words in given string are: 9

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM