簡體   English   中英

計算C中的一串數字中最頻繁出現的數字

[英]Compute the most frequent digit in a string of digits in C

我正在嘗試計算字符串中最頻繁出現的數字,我需要使用指針,但不確定如何使用指針。

int most(char* string){
    int counter = 0;
    int* array =(int*) malloc(sizeof(int)*10);
    char* original = string;
    while(*original){
        counter++;
        string++;
        //Not sure what to put in this loop
    }
}

例如,我想調用代碼

char nums[] = "132433423";
printf("%d \n",most(nums));
// 3

您的功能說明不完整:

  • 字符串可以包含非數字字符嗎?
  • 如果根本沒有數字應該返回什么?
  • 如果有多個數字出現的最大次數相同,應該返回哪個值?
  • 函數應返回數字還是其數字值? 您的main()函數使用后者,但是從問題的文本來看並不清楚。

most函數接收指向該字符串的指針。 您可以編寫一個循環,一次處理一個字符,然后遞增指針進行下一次迭代,直到到達字符串的末尾。 如果字符串不包含數字,則還必須決定返回什么。

這是一個簡單的示例:

int most(const char *s) {
    int count[10] = { 0 };
    int res, i, max;

    while (*s) {
        if (*s >= '0' && *s <= '9')
            count[*s - '0']++;
        s++;
    }
    res = -1;  /* return -1 if no digits */
    max = 0;
    for (i = 0; i < 10; i++) {
        if (count[i] > max)
            res = i;
    }
    return res;
}

如果完全不能使用任何數組,那么分配內存塊確實是一個不錯的解決方案:

int most(const char *s) {
    int *count = calloc(sizeof(*count), 10);
    int res, i, max;

    while (*s) {
        if (*s >= '0' && *s <= '9')
            *(count + *s - '0') += 1;
        s++;
    }
    res = -1;  /* return -1 if no digits */
    max = 0;
    for (i = 0; i < 10; i++) {
        if (*(count + i) > max)
            res = i;
    }
    free(count);
    return res;
}

*(count + *s - '0') += 1工作方式是這樣的: count是指向由calloc分配並初始化為0int數組的指針。 *s - '0's指向的字符的數字值n,已被測試為數字。 count + *s - '0'是指向數組中第n個條目的指針。 *(count + *s - '0') += 1將該值加1。

有多種方法可以在沒有內存分配的情況下進行操作,其中有10個變量和針對不同數字的顯式測試,但是我懷疑這是否是理想的解決方案。

如果可以向老師解釋您的選擇,則有兩種使用不帶[]字符的數組的方法。 這些是C標准的過時功能,大多數程序員都不熟悉這些功能,除非您感到好奇,否則可以忽略這些功能:

int most(const char *s) {  /* version with C99 digraphs */
    int count<:10:> = { 0 };
    int res, i, max;

    while (*s) {
        if (*s >= '0' && *s <= '9')
            count<:*s - '0':>++;
        s++;
    }
    res = -1;  /* return -1 if no digits */
    max = 0;
    for (i = 0; i < 10; i++) {
        if (count<:i:> > max)
            res = i;
    }
    return res;
}

要么

int most(const char *s) {  /* version with old-style trigraphs */
    int count??(10??) = { 0 };
    int res, i, max;

    while (*s) {
        if (*s >= '0' && *s <= '9')
            count??(*s - '0'??)++;
        s++;
    }
    res = -1;  /* return -1 if no digits */
    max = 0;
    for (i = 0; i < 10; i++) {
        if (count??(i??) > max)
            res = i;
    }
    return res;
}

我不確定“使用指針”是什么意思,但這是一個版本,除了遍歷輸入字符串外, 它不使用指針:

char most_frequent_character(char *s)
  {
  int freq[10];
  int max_freq;
  int max_idx;
  int idx;

  while(*s)
    freq[*s++ - '0']++;  /* compute character freqs */

  max_idx = 0;
  max_freq = freq[0];

  for(idx = 1 ; idx < 10 ; ++idx)
    if(freq[idx] > max_freq)
      {
      max_freq = freq[idx];
      max_idx = i;
      }

  return '0' + max_idx;
  }

玩得開心。


編輯

要將以上內容轉換為“使用指針”:

A.將freq更改為指向int的指針,並使用malloc對其進行初始化; 另外,使用memset初始化freq指向的內存:

int *freq = malloc(sizeof(int) * 10);
memset(freq, 0, sizeof(int)*10);

B.在“計算字符頻率”循環中,使用指針引用而不是索引:

while(*s)
  {
  *(freq + (*s - '0')) = *(freq + (*s - '0')) + 1;
  s++;
  }

C.使用指針ref設置max_freq的初始值:

max_freq = *freq;

D.在for循環中,使用指針數學代替索引:

  for(idx = 1 ; idx < 10 ; ++idx)
    if( *(freq + idx) > max_freq)
      {
      max_freq = *(freq + idx);
      max_idx = i;
      }

E.釋放在return語句之前分配的內存:

free(freq);
return '0' + max_idx;

現在,坐下來,了解為什么事情以它們在這里的方式完成。 例如,為什么在計算字符頻率時執行以下操作?

while(*s++)
  *(freq + (*s - '0')) = *(freq + (*s - '0')) + 1;

要么

while(*s)
  *(freq + (*s++ - '0')) = *(freq + (*s++ - '0')) + 1;

上面的每一項都會節省幾行代碼-為什么不使用它們? (最明顯的答案是“因為它們不會按預期工作”,但是為什么?)

祝你好運。

#include<string.h>    
int most (char* nums) {
    int i, max_index = 0;
    int digit_dictionary[10]={0,0,0,0,0,0,0,0,0,0};

    for (i=0; i< strlen(nums); i++) {
        digit_dictionary[nums[i]-'0'] ++;
    }

    for (i=1; i<10; i++) {
        if (digit_dictionary[i]> digit_dictionary[max_index])
            max_index = i;
    }
    return max_index;
}

我將盡我所能:

您創建一個詞典,其中每個索引都對應一個可能出現的數字(0-9)。 然后,遍歷字符串(基本上是字符數組),並將每個數字存儲到字典中的相應索引。
注意[nums[i]-'0']計算到字典的索引中,因為每個字符都有一個整數值(查找ASCII表)。

該索引處的計數器遞增,以保持該數字出現次數的計數。

之后,瀏覽字典以確定出現次數最多的數字在哪個位置,然后返回該數字。

您可以首先對字符串進行排序,以便較小的數字字符在num首先出現。 您可以使用qsort() (來自stdlib.h )像

int cmpfn(const void *a, const void *b)
{
    int x = *(char *)a;
    int y = *(char *)b;
    return x-y;
}
int main()
{
    char nums[] = "132433423";//"111222223333";//
    qsort(nums, sizeof(nums)/sizeof(nums[0]) -1, sizeof(nums[0]), cmpfn);
    printf("\nAfter sorting: %s", nums);

    . . . . . . . . . . 
    . . . . . . . . . . 

}

聲明變量以存儲模式 (即,數據中最頻繁出現的值)和模式值的頻率。

int mode=-1, modecount=-1, n;

現在找到每個數字字符的頻率。 由於這是一個排序的字符數組,因此相同的值將連續出現。

for(char *ptr=nums, *lptr=NULL; *ptr; ptr+=n)
{
    lptr = strrchr(ptr, *ptr);
    n = lptr - ptr + 1;
    if(n>modecount)
    {
        printf("\n%c", *ptr);
        modecount = n;
        mode = *ptr;
    }
}   
printf("\nMode is: %c", mode);

strrchr() (來自string.h )將找到字符串中字符的最后一次出現。

暫無
暫無

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

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