【问题标题】:Count the number of occurrences of each letter in string计算字符串中每个字母出现的次数
【发布时间】:2012-11-03 20:56:15
【问题描述】:

如何计算字符串中每个字母(忽略大小写)在 c 中出现的次数?所以它会打印出letter: # number of occurences,我有代码来计算一个字母的出现次数,但是如何计算字符串中每个字母的出现次数?

{
    char
    int count = 0;
    int i;

    //int length = strlen(string);

    for (i = 0; i < 20; i++)
    {
        if (string[i] == ch)
        {
            count++;
        }
    }

    return count;
}

输出:

a : 1
b : 0
c : 2
etc...

【问题讨论】:

    标签: c char


    【解决方案1】:

    假设您有一个系统,其中char 是 8 位,并且您尝试计数的所有字符都使用非负数编码。在这种情况下,你可以写:

    const char *str = "The quick brown fox jumped over the lazy dog.";
    
    int counts[256] = { 0 };
    
    int i;
    size_t len = strlen(str);
    
    for (i = 0; i < len; i++) {
        counts[(int)(str[i])]++;
    }
    
    for (i = 0; i < 256; i++) {
        if ( count[i] != 0) {
            printf("The %c. character has %d occurrences.\n", i, counts[i]);
        }
    }
    

    请注意,这将计算字符串中的所有字符。如果你 100% 绝对肯定你的字符串里面只有字母(没有数字、没有空格、没有标点符号),那么 1. 要求“不区分大小写”开始有意义,2. 你可以减少条目的数量到英文字母表中的字符数(即26),你可以这样写:

    #include <ctype.h>
    #include <string.h>
    #include <stdlib.h>
    
    const char *str = "TheQuickBrownFoxJumpedOverTheLazyDog";
    
    int counts[26] = { 0 };
    
    int i;
    size_t len = strlen(str);
    
    for (i = 0; i < len; i++) {
        // Just in order that we don't shout ourselves in the foot
        char c = str[i];
        if (!isalpha(c)) continue;
    
        counts[(int)(tolower(c) - 'a')]++;
    }
    
    for (i = 0; i < 26; i++) {
        printf("'%c' has %2d occurrences.\n", i + 'a', counts[i]);
    }
    

    【讨论】:

    • 这段代码给了我这个:0. 字符有 0 次出现。 1. 字符出现 0 次。 .....
    • @user1786283 您列出的是 dash (-)。我不相信你明白了。
    • @user1786283 Aaaaaaand... 这有什么问题?这意味着字符 0x00 的出现次数为零。等等。您知道,终端窗口右侧有一个滚动条,以防您使用基于 GUI 的现代操作系统。另外,你有没有尝试过剪掉第二个代码?
    • size_t len = strlen(str); ^~~~~~~~~~~ Untitled.c:12:1: error: expected identifier or '(' for (i = 0; i
    • 如果char默认签名,则代码不正确。在将str[i] 用作counts 的索引或isalpha() 的参数之前,您应该将str[i] 转换为(unsigned char)str[i]。否则,负字符值将导致未定义的行为。
    【解决方案2】:

    像这样:

    int counts[26];
    memset(counts, 0, sizeof(counts));
    char *p = string;
    while (*p) {
        counts[tolower(*p++) - 'a']++;
    }
    

    此代码假定字符串以 null 结尾,并且仅包含字符 azAZ,包括这些字符。

    要了解它是如何工作的,请回想在转换后tolower 每个字母在az 之间都有一个代码,并且代码是连续的。因此,tolower(*p) - 'a' 的计算结果为从 025(含)的一个数字,表示字母在字母表中的序号。

    这段代码结合了++*p来缩短程序。

    【讨论】:

    • 糟糕,实际上我们都没有完全关注 OP ;-) “忽略大小写”就是他的意思。
    • @H2CO3 你说得对,谢谢!我添加了tolower,并扩展了假设。非常感谢!
    • 如果字符串包含非字母字符时的未定义行为。
    【解决方案3】:

    一种简单的可能性是创建一个由 26 个整数组成的数组,每个整数都是一个字母 a-z 的计数:

    int alphacount[26] = {0}; //[0] = 'a', [1] = 'b', etc
    

    然后循环遍历字符串并增加每个字母的计数:

    for(int i = 0; i<strlen(mystring); i++)      //for the whole length of the string
        if(isalpha(mystring[i]))
            alphacount[tolower(mystring[i])-'a']++;  //make the letter lower case (if it's not)
                                                     //then use it as an offset into the array
                                                     //and increment
    

    这是一个适用于 A-Z、a-z 的简单想法。如果你想用大写分隔,你只需要将计数改为 52 并减去正确的 ASCII 偏移量

    【讨论】:

    • char值的未定义行为,低效的循环测试表达式,代码假定小写字母在字符集中是连续的。
    【解决方案4】:
    #include <stdio.h>
    #include <string.h>
    void main()
    {
        printf("PLEASE ENTER A STRING\n");
        printf("GIVE ONLY ONE SPACE BETWEEN WORDS\n");
        printf("PRESS ENETR WHEN FINISHED\n");
    
        char str[100];
        int arr[26]={0};
        char ch;
        int i;
    
        gets(str);
        int n=strlen(str);
    
        for(i=0;i<n;i++)
        {
            ch=tolower(str[i]);
            if(ch>=97 && ch<=122)   
            {
                arr[ch-97]++;
            }
        }
        for(i=97;i<=122;i++)
            printf("%c OCCURS %d NUMBER OF TIMES\n",i,arr[i-97]);   
        return 0;
    }
    

    【讨论】:

    • 这给出了一个字符出现在给定字符串中的次数。
    【解决方案5】:

    接受答案后

    满足这些规范的方法:(IMO,其他答案并不完全满足)

    1. char 具有 范围时,它是实用/高效的。示例:CHAR_BIT1632,所以不使用 bool Used[1 &lt;&lt; CHAR_BIT];

    2. 适用于非常长字符串(使用size_t而不是int)。

    3. 不依赖 ASCII。 (Use Upper[])

    4. EOFunsigned char 定义char is...() 函数

      static const char Upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      static const char Lower[] = "abcdefghijklmnopqrstuvwxyz";
      
      void LetterOccurrences(size_t *Count, const char *s) {
        memset(Count, 0, sizeof *Count * 26);
        while (*s) {
          unsigned char ch = *s;
          if (isalpha(ch)) {
            const char *caseset = Upper;
            char *p = strchr(caseset, ch);
            if (p == NULL) {
              caseset = Lower;
              p = strchr(caseset, ch);
            }
            if (p != NULL) {
              Count[p - caseset]++;
            }
          }
        }
      }
      
      // sample usage
      char *s = foo();
      size_t Count[26];
      LetterOccurrences(Count, s);
      for (int i=0; i<26; i++)
        printf("%c : %zu\n", Upper[i], Count[i]);
      }
      

    【讨论】:

      【解决方案6】:

      您可以使用以下代码。

      main()
      {
          int i = 0,j=0,count[26]={0};
          char ch = 97;
          char string[100]="Hello how are you buddy ?";
          for (i = 0; i < 100; i++)
          {
              for(j=0;j<26;j++)
                  {
                  if (tolower(string[i]) == (ch+j))
                      {
                          count[j]++;
                      }
              }
          }
          for(j=0;j<26;j++)
              {
      
                  printf("\n%c -> %d",97+j,count[j]);
      
          }
      
      }
      

      希望这会有所帮助。

      【讨论】:

      • 对于字符串The quick brown fox jumps over the lazy dog.,它给了我a -&gt; 0 b -&gt; 1 c -&gt; 1 d -&gt; 0 e -&gt; 1 f -&gt; 1 g -&gt; 0 h -&gt; 1 i -&gt; 1 j -&gt; 0 k -&gt; 1 l -&gt; 0 m -&gt; 0 n -&gt; 1 o -&gt; 2 p -&gt; 0 q -&gt; 1 r -&gt; 1 s -&gt; 0 t -&gt; 1 u -&gt; 1 v -&gt; 0 w -&gt; 1 x -&gt; 1 y -&gt; 0 z -&gt; 0,但每个字母都应该是1。
      • @user1786283 你确定你没有写“jumped”吗?
      • 对负 char 值的未定义行为、对小写字母的低效测试、硬编码的 ASCII 代码、损坏的缩进...
      【解决方案7】:
      #include<stdio.h>
      #include<string.h>
      
      #define filename "somefile.txt"
      
      int main()
      {
          FILE *fp;
          int count[26] = {0}, i, c;  
          char ch;
          char alpha[27] = "abcdefghijklmnopqrstuwxyz";
          fp = fopen(filename,"r");
          if(fp == NULL)
              printf("file not found\n");
          while( (ch = fgetc(fp)) != EOF) {
              c = 0;
              while(alpha[c] != '\0') {
      
                  if(alpha[c] == ch) {
                      count[c]++; 
                  }
                  c++;
              }
          }
          for(i = 0; i<26;i++) {
              printf("character %c occured %d number of times\n",alpha[i], count[i]);
          }
          return 0;
      }
      

      【讨论】:

      • 由于您没有退出函数而无法打开文件时的未定义行为。 ch 必须定义为 int 以进行正确的 EOF 检测。
      【解决方案8】:
      for (int i=0;i<word.length();i++){
               int counter=0;
               for (int j=0;j<word.length();j++){
                   if(word.charAt(i)==word.charAt(j))
                   counter++;
                   }// inner for
                   JOptionPane.showMessageDialog( null,word.charAt(i)+" found "+ counter +" times");
               }// outer for
      

      【讨论】:

        【解决方案9】:
        #include<stdio.h>
        
        void frequency_counter(char* str)
        {
            int count[256] = {0};  //partial initialization
            int i;
        
            for(i=0;str[i];i++)
                count[str[i]]++;
        
            for(i=0;str[i];i++) {
                if(count[str[i]]) {
                    printf("%c %d \n",str[i],count[str[i]]);
                    count[str[i]]=0;
                }
            }
        }
        
        void main()
        {
            char str[] = "The quick brown fox jumped over the lazy dog.";
            frequency_counter(str);
        }
        

        【讨论】:

        • 什么是frequency_counter
        • 欢迎写一点来解释这段代码
        • char 值在用作 indexx 值时必须转换为 unsigned charcount[(unsigned char)str[i]]++;
        【解决方案10】:

        这是带有用户定义函数的 C 代码:

        /* C Program to count the frequency of characters in a given String */
        
        #include <stdio.h>
        #include <string.h>
        
        const char letters[] = "abcdefghijklmnopqrstuvwxzy";
        
        void find_frequency(const char *string, int *count);
        
        int main() {
            char string[100];
            int count[26] = { 0 };
            int i;
        
            printf("Input a string: ");
            if (!fgets(string, sizeof string, stdin))
                return 1;
        
            find_frequency(string, count);
        
            printf("Character Counts\n");
        
            for (i = 0; i < 26; i++) {
                printf("%c\t%d\n", letters[i], count[i]);
            }
            return 0;
        }
        
        void find_frequency(const char *string, int *count) {
            int i;
            for (i = 0; string[i] != '\0'; i++) {
                p = strchr(letters, string[i]);
                if (p != NULL) {
                    count[p - letters]++;
                }
            }
        }
        

        【讨论】:

        • 如果本机字符中的小写字母不连续(如 EBCDIC),则行为未定义。 gets() 已过时且危险。
        【解决方案11】:

        已经检查了许多答案都是静态数组,如果假设我在字符串中有特殊字符并想要一个具有动态概念的解决方案怎么办。可能还有许多其他可能的解决方案,它就是其中之一。

        这里是链接列表的解决方案。

        #include <stdio.h>
        #include <string.h>
        #include <stdlib.h>
        
        struct Node { 
            char data; 
            int counter;
            struct Node* next; 
        };
        
        void printLinkList(struct Node* head)
        {
            while (head != NULL) { 
                printf("\n%c occur %d", head->data, head->counter);
                head = head->next;
            }
        }
        
        int main(void) {
            char *str = "!count all the occurances of character in string!";
            int i = 0;
            char tempChar;
            struct Node* head = NULL; 
            struct Node* node = NULL; 
            struct Node* first = NULL; 
        
            for(i = 0; i < strlen(str); i++)
            {
                tempChar = str[i];
        
                head = first;
        
                if(head == NULL)
                {
                    node = (struct Node*)malloc(sizeof(struct Node));
                    node->data = tempChar;
                    node->counter = 1;
                    node->next = NULL;
        
                    if(first == NULL)
                    {
                        first = node;
                    }
                }
                else
                {
                    while (head->next != NULL) { 
                        if(head->data == tempChar)
                        {
                            head->counter = head->counter + 1;
                            break;
                        }
                        head = head->next;
                    }
        
                    if(head->next == NULL)
                    {
                        if(head->data == tempChar)
                        {
                            head->counter = head->counter + 1;
                        }
                        else
                        {
                            node = (struct Node*)malloc(sizeof(struct Node));
                            node->data = tempChar;
                            node->counter = 1;
                            node->next = NULL;
                            head->next = node;
                        }
                    }
                }
            }
        
            printLinkList(first);
        
        
            return 0;
        }
        

        【讨论】:

          【解决方案12】:
          int charset[256] = {0};
          int charcount[256] = {0};
          
          for (i = 0; i < 20; i++)
          {
              for(int c = 0; c < 256; c++)
              {
                  if(string[i] == charset[c])
                  {
                     charcount[c]++;
                  }
              }
          }
          

          charcount 将存储字符串中任何字符的出现次数。

          【讨论】:

          • 这段代码坏了:charset的所有元素都是0
          【解决方案13】:

          //这是 JavaScript 代码。

          function countWordOccurences()
          {
              // You can use array of words or a sentence split with space.
              var sentence = "The quick brown fox jumped over the lazy dog.";
              //var sentenceArray = ['asdf', 'asdf', 'sfd', 'qwr', 'qwr'];
              var sentenceArray = sentence.split(' ', 1000); 
              var output;
              var temp;
              for(var i = 0; i < sentenceArray.length; i++) {
                  var k = 1;
                  for(var j = i + 1; j < sentenceArray.length; j++) {
                      if(sentenceArray[i] == sentenceArray[j])
                              k = k + 1;
                  }
                  if(k > 1) {
                      i = i + 1;
                      output = output + ',' + k + ',' + k;
                  }
                  else
                      output = output + ',' + k;
              }
              alert(sentenceArray + '\n' + output.slice(10).split(',', 500));
          }
          
          You can see it live --> http://jsfiddle.net/rammipr/ahq8nxpf/
          

          【讨论】:

          • 这不是问题的答案... OP 要求的是 C 程序,而不是 JavaScript。
          【解决方案14】:

          //计算字符串中每个字符出现次数的c代码。

          void main()
             {
             int i,j; int c[26],count=0; char a[]="shahid";
             clrscr();
             for(i=0;i<26;i++)
              {
                  count=0;
                    for(j=0;j<strlen(a);j++)
                          {
                           if(a[j]==97+i)
                              {
                               count++;
                                   }
                                     }
                            c[i]=count;
                         }
                        for(i=0;i<26;i++)
                         {
                        j=97+i;
                    if(c[i]!=0) {  printf("%c of %d times\n",j,c[i]);
                           }
                        }
                     getch();
                     }
          

          【讨论】:

          • 问题多多:这个方案效率极低,代码随机缩进,使用硬编码的ASCII值,非标准函数,main()的原型无效,头文件丢失跨度>
          【解决方案15】:
          protected void btnSave_Click(object sender, EventArgs e)
              {           
                  var FullName = "stackoverflow"
          
                  char[] charArray = FullName.ToLower().ToCharArray();
                  Dictionary<char, int> counter = new Dictionary<char, int>();
                  int tempVar = 0;
                  foreach (var item in charArray)
                  {
                      if (counter.TryGetValue(item, out tempVar))
                      {
                          counter[item] += 1;
                      }
                      else
                      {
                          counter.Add(item, 1);
                      }
                  }
                  //var numberofchars = "";
                  foreach (KeyValuePair<char, int> item in counter)
                  {
                      if (counter.Count > 0)
                      {
                          //Label1.Text=split(item.
                      }
                      Response.Write(item.Value + " " + item.Key + "<br />");
                      // Label1.Text=item.Value + " " + item.Key + "<br />";
                      spnDisplay.InnerText= item.Value + " " + item.Key + "<br />";
                  }
          
              }
          

          【讨论】:

          • 添加一些解释,说明此答案如何帮助 OP 解决当前问题
          猜你喜欢
          • 2016-01-23
          • 2020-07-23
          • 1970-01-01
          • 2022-10-15
          • 1970-01-01
          • 2019-04-05
          • 2013-11-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多