Home > OS >  Find the position of a max on a number
Find the position of a max on a number

Time:11-19

I have C program that needs to find the position of a number. It goes like this:

From standard input we enter unknown number of number that are positive. The numbers have maximum of 5 digits, we read new numbers till the user enters a value that is not a number. I need to find the positions of the max digit of a number from right to left. Use the right-most position if there are more than one instance of the max digit.

The program needs to output the position and the number of times the max digit of a number was found at that position.

For example:
input:

97654 48654 12345 12343 1263 12443 12643  12777 #

output:

0: 2
1: 3
2: 1
3: 1
4: 1

because

Position: 4      3        0    1    1     1    2        0
          v      v        v    v    v     v    v        v
          97654 48654 12345 12343 1263 12443 12643  12777 #

THE PROGRAM WORKS FOR THIS SPECIFIC TEST CASE

More test cases under the code.

Here is my code:

#include <stdio.h>

int main(){
    int n;
    int max;
    int num,digit,pos,br0=0,br1=0,br2=0,br3=0,br4=0;
    while (scanf("%d",&n)) {
        max =0;
        num = n;
        pos=0;
        while (num>0) {

            digit = num%10;
            if(digit > max){
                max=digit;
                pos  ;
            }
            num/=10;

        }
                    printf("%d\n",pos);
        switch (pos) {
            case 1: br0  ; break;
            case 2: br1  ; break;
            case 3: br2  ; break;
            case 4: br3  ; break;
            case 5: br4  ; break;
        }
    }
    printf("0: %d\n1: %d\n2: %d\n3: %d\n4: %d\n",br0,br1,br2,br3,br4);
    return 0;
}

This program work for some test cases, such as

97654 48654 12345 12343 1263 12443 12643 12777 #
123 456 789 987 654 321 #

But not for:

542 8965 7452 1111 12 8 6532 98745 15926 #
75386 86142 94285 15926 35724 #

CodePudding user response:

The problem with your program is that within this loop

    while (num>0) {

        digit = num%10;
        if(digit > max){
            max=digit;
            pos  ;
        }
        num/=10;

    }

the variable pos is incremented only when a digit that is greater than previous digits is found. For example If you have a number like this

51234 

then the first largest digit is 4 and the variable pos is set to 1. After that when the next largest digit is found that is the digit 5 the variable pos is incremented and becomes equal to 2 while actually the largest digit 5 is at the position 5.

You need to introduce one more variable as for example

    max =0;
    num = n;
    pos=1;

    int i = 1;

    do
    {
        digit = num%10;
        if(digit > max){
            max=digit;
            pos = i;
        }
     } while ( ( num /=10 ) && ( i   != 5 ) );

I would write the program the following way

#include <stdio.h>

int main(void) 
{
    enum { N = 5 };
    const unsigned int Base = 10;
    
    size_t total[N] = { 0 };
    
    unsigned int n;
    
    while ( scanf( "%u", &n ) == 1 )
    {
        unsigned int pos = 0;
        unsigned int max_digit = 0;
        unsigned int i = 0;
        
        do
        {
            unsigned int current_digit = n % Base;
            
            if ( max_digit < current_digit )
            {
                pos = i;
                max_digit = current_digit;
            }
        } while ( ( n /= Base ) && (   i != N ) );
        
          total[pos];
    }
    
    for ( unsigned int i = 0; i < N; i   )
    {
        printf( "%u: %zu\n", i, total[i] );
    }
    
    return 0;
}

For the input

542 8965 7452 1111 12 8 6532 98745 15926 #

the program output is

0: 3
1: 0
2: 3
3: 2
4: 1

CodePudding user response:

It may be fewer steps to do the work using fgets(), and keeping the input in string format. (verifying that it contains numeric characters.) Plus, an array of values will be easier to keep tract of value to index relationships.

Here is an alternate way of getting the information you describe:

int main(void) {
    char inBuf[20] = {0};
    int index = 0;
    int loops = 0;
    int maxPos = 0;
    int maxVal = 0;
    
    printf("Enter a number : ");
    while (fgets(inBuf, sizeof inBuf, stdin) && loops < 6) {
        
        inBuf[strcspn(inBuf, "\r\n")] = 0;//remove unwanted white space
         if(strstr(inBuf, "#")) return 0;//exit if "#"
        if(digits_only(inBuf))
        {
            index = 0;
            maxVal = inBuf[index];
            while(inBuf[index])
            {
                if(inBuf[index] >= maxVal)
                {
                   maxVal = inBuf[index];
                   maxPos = index;
                }
                index  ;                    
            }
            printf("%d:%d \n", loops, maxPos);
            loops  ;
            inBuf[0]=0;

        }
        else
        {
            printf("\n%s contains non-numeric characters, it cannot be converted.\n\nctrl-c to exit\n...Or enter a number : \n", inBuf);
        }
    };
    return 0;
}

CodePudding user response:

scanf is the wrong tool for this. (scanf is (almost) always the wrong tool). For this particular problem, you really want to treat the input as a string. As long as you don't want to accept inputs that look like "1e3" (which is a perfectly valid representation of an integer), you could just do something like:

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

int
main(void){
    int max = -1;
    int br[5] = {0};
    int maxpos = -1;
    int len = 0;
    int c;
    while( (c = getchar()) != EOF ){
        if( c && strchr("0123456789", c) ){
            if(   len > 5 ){
                fputs("invalid input\n", stderr);
                return 1;
            }
            assert( len > 0 && len < 6 );
            if( c > max   '0' ){
                maxpos = len;
                max = c - '0';
            }
        } else if( isspace(c) ){
            if( max > -1 ){
                br[len - maxpos]  = 1;
            }
            maxpos = -1;
            len = 0;
            max = '0' - 1;
        } else {
            fputs("invalid input\n", stderr);
            return 1;
        }
    }
    for( int i = 0; i < 5; i   ){
        printf("%d: %d\n", i, br[i]);
    }
    return 0;
}
  • Related