Digit frequency program for large input

牧云@^-^@ 提交于 2019-12-08 09:17:54

问题


I have written the below program to find out number of times each digit is occurring in the array of characters.

int main(){

    char s[2000],count,j=0;
    fgets(s,2000,stdin);
    for(int i=0;i<=9;i++)
    {
        count=0;j=0;
        while(*(s+j))
        {
            if(isdigit(*(s+j)))
            {
                if(i==(*(s+j)-'0'))
                    count++;
            }
            j++;    
        }
     printf("%d ",count);    
    }
    return 0;
}

But it ain't working for large input.

b3n47b5xf13qlx233rg4u2c949i623e34nt5661se06b675utbpy258wz633855846l761d61x340h1vn19w191sj18v2u333556bh6m5uc4u050am05p961dhmpu6iq4667zg9 

The expected output is

5 10 5 12 8 11 15 4 4 6 

But the output I got is

5 10 5 12 7 11 13 3 4 5 

Can anyone help me out in finding where I have gone wrong?


回答1:


In addition to DYZ's answer, your logic is convoluted. You don't need to test both if(isdigit(*(s+j))) and if(i==(*(s+j)-'0')), you simply need to refactor you code and provide a single test and use a frequency array.

(a simple array with 10 elements initialized to all zero where you increment the index that corresponds to each digit when that digit is found resulting in the count of that digit being present at the corresponding index when done)

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

#define MAXC 2048   /* if you need a constant, #define one (or more) */
#define NDIGIT 10

int main (void) {

    char s[MAXC] = "";
    size_t digits[NDIGIT] = {0};    /* declare a 'frequency array' */

    while (fgets (s, MAXC, stdin)) {    /* read all blocks of data */
        char *p = s;                    /* pointer to s */
        while (*p) {                    /* for each char in s */
            if (isdigit (*p))           /* Am I a digit? */
                digits[*p - '0']++;     /* increment value at index */
            p++;                        /* increment pointer */
        }
    }

    for (int i = 0; i < NDIGIT; i++)
        printf (" %zu", digits[i]);
    putchar ('\n');

    return 0;
}

Or without ctype.h,

#include <stdio.h>

#define MAXC 2048   /* if you need a constant, #define one (or more) */
#define NDIGIT 10

int main (void) {

    char s[MAXC] = "";
    size_t digits[NDIGIT] = {0};    /* declare a 'frequency array' */

    while (fgets (s, MAXC, stdin)) {    /* read all blocks of data */
        char *p = s;                    /* pointer to s */
        while (*p) {                    /* for each char in s */
            if ('0' <= *p && *p <= '9') /* Am I a digit? */
                digits[*p - '0']++;     /* increment value at index */
            p++;                        /* increment pointer */
        }
    }

    for (int i = 0; i < NDIGIT; i++)
        printf (" %zu", digits[i]);
    putchar ('\n');

    return 0;
}

Example Use/Output

In both cases, the output with your input is:

 5 10 5 12 8 11 15 4 4 6

Look things over and let me know if you have further questions.




回答2:


You declared j as char (and count, too, but it's a different issue). The largest value of a (signed) char variable is 127. When your string has more than 128 characters, j overflows: j+1 becomes -128 rather than 128. Declare all variables that are used for indexing and counting as int or size_t.



来源:https://stackoverflow.com/questions/51681553/digit-frequency-program-for-large-input

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!