• 统计字符串中单词个数


    复制代码

    要求:输入一个字符串,统计每个单词的个数。单词间用空格隔开,可多个空格,写出自己认为高效的算法。

    例如:输入:I love love China
    输出为:
    I:
    1
    love:
    2
    China:
    1
    复制代码

    首先想到的还是模拟的方法,就是用struct把出现过的单词缓存起来,然后再输入文本中遍历到新单词的时候,遍历一次struct,看这个单词是不是已经存,做相关处理。
    如果输入文本中有n个字母,不重复的字母为m个, 则算法复杂度为O(nm^2) 最好情况是m =1 ,最差情况是m=n 其实现代码如下:

     1 #include <stdio.h>
     2  #include <string.h>
     3   struct struct_words{
     4          char word[20];
     5          int count;
     6  };
     7   int main(){
     8          char string[100];
     9          char c;
    10          struct struct_words words[20];
    11          int i = 0, k = 0 , ws =0;
    12  
    13          for(; i < 20; i++){
    14                  words[i].word[0] = '\0';
    15                  words[i].count = 0;
    16          }
    17          puts("please input words.");
    18          gets(string);
    19          puts("=============开始取词================");
    20  
    21          i = 0;
    22          do{
    23                  c = string[i];
    24                  if(c != ' ' && c !='\0'){
    25                          words[k].word[ws] = c;
    26                          words[k].count = 1;
    27                          ws ++;
    28                  }else{
    29                          words[k].word[ws] = '\0';
    30                          ws = 0;
    31                          k ++;
    32                  }
    33                  i ++;
    34          }while(c!='\0');lda
    35  
    36  
    37          puts("=========== 合并相同的单词 ==============");
    38          for(i = 0; words[i].word[0] != '\0' ; i++){
    39                  puts(words[i].word);
    40                  if( words[i].count >= 1)
    41                  for(k = i; words[k].word[0] != '\0'; k++){
    42                          if(strcmp(words[i].word, words[k].word) == 0
    43                             && words[k].count == 1){
    44                                  words[k].count --;
    45                                  words[i].count ++;
    46                          }
    47                  }
    48          }
    49  
    50          puts("=============== End ==============");
    51          for(i = 0;words[i].word[0] != '\0' ;i++){
    52                  if(words[i].count != 0 )
    53                          printf("%s:\t\t%d\n",words[i].word, words[i].count);
    54          }
    55          return(0);
    56  }


    然后呢,做一下优化,恩路是遍历用户的输入文本是必须的,但是,单词的缓存和出现次数的统计是可以使用hash算法来优化的,借用hash算法的特性,使复杂度立刻就降低到了 O(n),实现代码如下:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #define N 100
     4 
     5 struct struct_words{
     6     char word[100];
     7     int count;
     8 };
     9 
    10 int hash(char* key)
    11 {
    12      unsigned long h=0;
    13       while(*key)
    14            {   
    15                  h=(h<<4)+*key++;
    16                    unsigned long g=h & 0xF0000000L;
    17                      if(g)
    18                             h^=g>>24;
    19                        h&=~g;
    20                         }   
    21        return h&N;
    22 }
    23 int main(){
    24     char string[1000];
    25     char current_word[100];
    26     char c;
    27     struct struct_words words[200]; 
    28     int i = 0, k = 0 , ws =0 , key;
    29     int keys[100];
    30 
    31     for(; i < 200; i++){
    32         words[i].word[0] = '\0';
    33         words[i].count = 0;
    34     }   
    35     puts("=============输入一些单词,用空格隔开================");
    36     gets(string);
    37 
    38     i = 0;
    39     do{ 
    40         c = string[i];
    41         //如果第一个单词前有空格,跳过去
    42         if( ws == 0  && c == ' ') {i++ ; continue;}
    43         if(c != ' ' && c !='\0'){
    44             current_word[ws] = c;
    45             ws ++; 
    46         }else{
    47             current_word[ws] = '\0';
    48             key = hash(current_word);
    49             if(words[key].count == 0){ 
    50                 strcpy(words[key].word, current_word);
    51                 keys[k] = key;
    52                 k++;
    53             }   
    54             words[key].count ++; 
    55             ws = 0;
    56         }
    57     i ++;
    58     }while(c != '\0');
    59 
    60     printf("%d" ,k);
    61     puts("===============打印結果 ==============");
    62     for(i = 0 ; i < k ;i++){
    63             printf("%s:\t\t%d\n",words[keys[i]].word, words[keys[i]].count);
    64     }
    65     puts("=============== End ==============");
    66     return 0;
    67 }

     来源:http://www.cnblogs.com/amboyna/archive/2009/12/05/1617387.html


    微信公众号: 猿人谷
    如果您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】
    如果您希望与我交流互动,欢迎关注微信公众号
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

  • 相关阅读:
    Angular Universal教学-将现有专案导入Server Side Render
    [.NET] 使用ValidationContext快速进行模型资料的验证
    FINS/TCP_OMRON(1)
    C#中字段、属性、只读、构造函数赋值、反射赋值的相关
    async异步方法
    C# GetHashCode、Equals函数和键值对集合的关系
    JS三个编码函数和net编码System.Web.HttpUtility.UrlEncode比较
    ES6摘抄
    js基础
    js自执行函数、调用递归函数、圆括号运算符、函数声明的提升
  • 原文地址:https://www.cnblogs.com/heyonggang/p/3066911.html
Copyright © 2020-2023  润新知