簡體   English   中英

在 C 中查找最常見的字母

[英]Find most frequent letter in C

這是我在字符串中查找最常見字母的代碼。 我需要將最常見的字母存儲在most_freq字符串中,它們也應該按字母順序排列。

我不知道如何處理有更多相同頻率的字母並且它們也是最頻繁的情況。

char text[200];
char most_freq[27];
int freq[26];
int i;
int counter;
int temp = 0;
int max_freq;

fgets(text, sizeof(text), stdin);
size_t len = strlen(text);
if (text[len - 1] == '\n') {
    text[len - 1] = '\0';
    len--;
}

for (i = 0; i < 26; i++) {
    freq[i] = 0;
}

for (i = 0; i < len; i++) {
    if (text[i] >= 'a' && text[i] <= 'z') {
        counter = text[i] - 'a';
        freq[counter]++;
    }
}

int max = 0;

for (i = 0; i < 26; i++) {
    if (freq[i] > temp) {
        temp = freq[i];
        max_freq = temp;
    }
    printf("%c occurs %d times.\n", i + 'a', freq[i]);

    if (freq[i] > freq[max]) {
        max = i;
    }
}

printf("Highest frequency: %d \n", max_freq);
//printf("%c \n",max+'a');
sprintf(most_freq, "%c", max + 'a');
puts(most_freq);
#include <stdio.h>
#include <ctype.h>

#define SIZE 99

int main() {

    char s[SIZE];
    int freq[26] = {0}, i, max = 0;
    
    fgets(s, SIZE, stdin);
    
    for(i = 0; s[i]; i++) {
        
        if( isalpha((unsigned char)s[i]) ) ++freq[s[i] - ( islower((unsigned char)s[i]) ? 'a' : 'A')];
    }
    
    for(i = 0; i < 26; i++) {
        
        if( max < freq[i] ) max = freq[i];
    }
    
    for(i = 0; i < 26; i++) {
        
        if( freq[i] == max ) putchar('a'+i);
    }
    
    return 0;
}

我首先計算所有字母頻率,然后找到最大字母頻率,最后找到打印所有字符以具有最大頻率。

這是我的解決方案。 我評論它以使其更清楚:

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

int main() {
  char   text[200] = { 0 };
  size_t freq[26]  = { 0 };

  // get the user's text
  fgets(text,sizeof(text),stdin);
  const size_t len = strlen(text);

  // calculate frequencies
  for (size_t i = 0; i < len; ++i)
    if (text[i] >= 'a' && text[i] <= 'z')
      ++freq[text[i]-'a'];

  size_t maxCount = 0;

  // find the maximum frequency and print each letter's frequency
  for (size_t i = 0; i < sizeof(freq); ++i) {
    if (freq[i] > maxCount)
      maxCount = freq[i];

    printf("%c occurs %d times.\n", i+'a', freq[i]);
  }

  printf("\n\n"); // padding

  // Print all characters with the maximum frequency
  for (size_t i = 0; i < sizeof(freq)/sizeof(freq[0]); ++i)
    if (freq[i] == maxCount)
      printf("%c occurs with maximum frequency.\n", 'a'+i);
}

編輯:您還可以通過使用 libc 的ctype.h header 文件中的tolower() function 使其適用於任何大小寫的字母來擴展您的程序,以便在計算其頻率時使所有字符小寫。

++freq[text[i]-'a']; 會變成++freq[tolower(text[i])-'a']; .

這是一個更簡單的版本:

#include <stdio.h>

int main() {
    char text[200];
    int freq[26] = { 0 };
    int max_freq = 0;

    // read use input or use the empty string
    if (!fgets(text, sizeof(text), stdin))
        *text = '\0';

    // compute frequencies, update maximum frequency
    for (int i = 0; text[i] != '\0'; i++) {
        if (text[i] >= 'a' && text[i] <= 'z') {
            int index = text[i] - 'a';     // assuming ASCII
            if (++freq[index] > max_freq)
                max_freq = freq[index];  // update maximum frequency
        }
    }

    // print characters with maximum frequency in alphabetical order
    for (int i = 0; i < 26; i++) {
        if (freq[i] == max_freq)
            putchar('a' + i);
    }

    putchar('\n');
    return 0;
}

通常,當想要任何 object 的頻率在指定范圍內時,您希望您的頻率陣列覆蓋該 object 的整個可能值范圍。 有關什么是頻率數組以及如何使用它的完整解釋,請在回答如何刪除 C 中的字符串中的重復字符時提供更完整的解釋

在這種情況下,對於 ASCII 字符,您有 128 個可能的值范圍(如果包含擴展的 ASCII 集,則為 256 個),請參閱ASCII 表和說明 通過創建包含 128(或 256)個元素的頻率陣列,您無需檢查特殊情況,例如小寫/大寫字符。

例如,您可以覆蓋所有 ASCII 字符,並使用以下內容查找用戶最常輸入的字符:

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

#define SIZE 256        /* size works for both frequency array and text as a multiple */

int main (void) {

    char text[SIZE * 4];                                /* 1024 byte buffer */
    int freq[SIZE] = {0}, max = 0;                      /* frequeny array & max */
    
    fputs ("enter string: ", stdout);                   /* prompt */
    if (!fgets (text, SIZE, stdin)) {                   /* read/validate EVERY input */
        puts ("(user canceled input)");
        return 0;
    }
    
    for (int i = 0; text[i]; i++)                       /* loop over each char */
        if (++freq[(unsigned char)text[i]] > max)       /* increment/check against max */
            max = freq[(unsigned char)text[i]];
    
    printf ("\nmost frequent appear %d times: ", max);
    for (int i = '!'; i < SIZE; i++)                    /* loop over freq array */
        if (freq[i] == max)                             /* if count == max */
            putchar (i);                                /* output char */
    
    putchar ('\n');                                     /* tidy up with newline */
}

注意:由於用戶可以通過按Ctrl + d或 windows 上的Ctrl + z來有效地取消生成手動EOF的輸入,因此最好驗證每個輸入並處理EOF情況以及任何其他可能的故障模式)

由於' ' (空格、 320x20 )下方的 ASCII 字符是不可打印的或空格,例如'\t''\n'\r等,因此您可以使用'!'開始 output 循環忽略空格的字符。 如果您需要每個字符的頻率,您可以創建一個簡短的查找表,其中包含每個不可打印或空白字符的字符串表示形式。 這樣,如果' '字符是最常見的字符或其中一個,您可以使用 output,例如"(sp)"或類似的東西, "(tab)"用於制表符等。

示例使用/輸出

$ ./bin/badfreq
enter string: 123+HH~helloo+345

most frequent appear 2 times: +3Hlo

將最常見的字符保存到數組

緩沖數組中最頻繁出現的字符而不是直接使用putchar()輸出它們所需的更改很少。 您需要做的就是聲明一個足夠大的數組以容納最大數量的可能字符(如果您希望將數組視為 C 字符串,則+1以允許空間用於nul 終止字符。

下面我們添加緩沖區(字符數組) most_freq[]來保存最常用的字符,並填充most_freq[]數組,我們在第一個示例中只是輸出它,例如

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

#define SIZE 256        /* size works for both frequency array and text as a multiple */

int main (void) {

    char text[SIZE * 4],                                /* 1024 byte read buffer */
         most_freq[SIZE + 1] = "";                      /* 257 byte buffer for storage */
    int freq[SIZE] = {0},                               /* frequeny array */
        max = 0,                                        /* times most frequent occurs */
        mf_ndx = 0;                                     /* most_frequent index */
    
    fputs ("enter string: ", stdout);                   /* prompt */
    if (!fgets (text, SIZE, stdin)) {                   /* read/validate EVERY input */
        puts ("(user canceled input)");
        return 0;
    }
    
    for (int i = 0; text[i]; i++)                       /* loop over each char */
        if (++freq[(unsigned char)text[i]] > max)       /* increment/check against max */
            max = freq[(unsigned char)text[i]];
    
    for (int i = '!'; i < SIZE; i++)                    /* loop over freq array */
        if (freq[i] == max)                             /* if count == max */
            most_freq[mf_ndx++] = i;                    /* store in most_freq array */
    most_freq[mf_ndx] = 0;                              /* nul-terminate as string */
    
    printf ("\n%d most frequent chars appear %d times: %s\n",   /* output results */
            mf_ndx, max, most_freq);
}

在我們用來填充數組的循環退出之后,我們在添加的最后一個字符之后添加以nul 終止的字符'\0' (與普通的舊 ASCII 0相同),這樣我們就可以將most_freq[]數組視為一個字符串。

示例使用/輸出

這確實允許一種簡單的方法在 output 中提供更多信息,例如

$ ./bin/most_freq_array
enter string: 123+HH~helloo+345

5 most frequent chars appear 2 times: +3Hlo

或者在您的"helloo"的具體示例中:

$ ./bin/most_freq_array
enter string: helloo

2 most frequent chars appear 2 times: lo

看看事情,讓我知道你是否還有其他問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM