Подсчет слов из строки с несколькими пустыми пробелами - PullRequest
0 голосов
/ 26 января 2019

Мне нужен код, который может считать слова из строки, не считая нескольких пробелов между ними.

Я мог бы закодировать программу, которая считает слова только с 1 пустым пробелом между ними, но я не знаюкак я должен кодировать его, когда это будет более 1 пустого места.Я думал что-то вроде for цикла, который проверяет, является ли символ перед пробелом, но я не знаю, как это сделать.И я хочу отметить, что я новичок в 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);
} 

Ответы [ 5 ]

0 голосов
/ 26 января 2019

Короткая и простая версия:

#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
0 голосов
/ 26 января 2019

считать слова из строки, не считая несколько пробелов между ними

Установите флаг, чтобы определить, возможно ли начало слова. Меньше особых случаев, чем поиск конца слова.

Обычно требование к "пробелам" подразумевает любое пустое пространство, тогда задача легко кодируется:

#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
0 голосов
/ 26 января 2019

немного более универсально

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));
}
0 голосов
/ 26 января 2019

Здесь помогает формулировка проблемы в общих чертах.Не думайте об этом, как о «подсчете слов» или «подсчете пробелов».Думайте об этом как о подсчете «переходов из разделителя в разделитель».Определение наших терминов:

  • Разделитель: начало строки или один пробел 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++

Здесь вы можете перевести на определенные языки или изменитьзначение разделителей без влияния на логику подсчета.

0 голосов
/ 26 января 2019

Вы можете ввести флаг, чтобы указать, был ли предыдущий символ пробелом.Что-то вроде:

#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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...