Нахождение частоты максимальной цифры в числе - PullRequest
2 голосов
/ 01 июня 2019
#include <stdio.h>

int main(void)
{
    int i=0,max=0;
    long long int n,p;
    scanf("%lld",&n);
    while(n>0)
    {
        p=n%10;
        if(p==max)
        {
            i++;
        }
        else if(p>max)
        {
            max=p;
            i=1;
        }
        n/=10;
    }
    printf("%d",i);
    return 0;
}

Код дает правильные результаты для чисел типа 8687557576676885 . Но для ввода 11111111111111111111111111111111 он не дает должного результата. Я видел подобную проблему на этом сайте, но они были написаны на другом языке. Я хочу знать, где проблема для большого числа.

Спасибо ...

N.B. : Было бы полезно, если бы кто-нибудь мог дать альтернативные решения. Я все еще новичок, так что это поможет мне глубже понять вещи.

Ответы [ 2 ]

1 голос
/ 01 июня 2019

В вашем коде переполнение.Я напечатал значение, прочитанное scanf, и результат таков:

11111111111111111111111111111111
7 0 922337203685477580
0 7 92233720368547758
8 7 9223372036854775
5 8 922337203685477
7 8 92233720368547
7 8 9223372036854
4 8 922337203685
5 8 92233720368
8 8 9223372036
6 8 922337203
3 8 92233720
0 8 9223372
2 8 922337
7 8 92233
3 8 9223
3 8 922
2 8 92
2 8 9
9 8 0
9 1

Я использовал этот модифицированный код:

#include <stdio.h>

int main(void)
{
  int count=0,max=0, digit;
  long long int n;
  scanf("%lld",&n);
  while(n)
  {
    digit=n%10,n/=10;
    printf("%d %d %lld\n",digit, max, n);
    if(digit==max)
      count++;
    else if(digit>max)
      max=digit,
      count=1;
  }
  printf("%d %d",max, count);
  return 0;
}

Чтобы избежать переполнения, вам нужно прочитать число какстрока char*number и обрабатывать цифры как символы.Вы должны сделать это так:

int main(void)
{
  int count=0;
  char max='0', digit;
  char n[1000], *p=n;
  fgets(n, 1000, stdin);
  while(*p)
    {
      digit=*p++;
      if(digit==max)
        count++;
      else if(digit>max)
        max=digit,
        count=1;
    }
  printf("%c %d",max, count);
  return 0;
}
1 голос
/ 01 июня 2019

Код дает правильные результаты для чисел, таких как 8687557576676885. Но для ввода 11111111111111111111111111111111

8687557576676885 требуется 53 бита, но 11111111111111111111111111111111 нужно 104 бита, слишком много для вашего long long вероятно на 64 битах

Было бы полезно, если бы кто-нибудь мог дать альтернативные решения

Вместо использования scanf используйте fgets или эквивалентный тогда strtoll , и вы сможете обнаружить переполнение, глядя на errno

Однако в вашем случае вам не нужно извлекать число, просто работайте со строкой, например, чтобы не быть ограниченным каким-либо размером:

#include <stdio.h>

int main(void)
{
  int i=0,max=-1;
  int c;

  while ((c = fgetc(stdin)) && (c != EOF) && (c != '\n')) {
    if ((c < '0') || (c > '9')) {
      printf("'%c' is not a valid digit\n", c);
      return -1;
    }
    c -= '0';
    if(c==max)
    {
      i++;
    }
    else if(c>max)
    {
      max=c;
      i=1;
    }
  }
  if (max != -1)
    printf("%d times %d\n",i, max);
  return 0;
}

Компиляция и исполнения:

pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra m.c
pi@raspberrypi:/tmp $ ./a.out
8687557576676885
4 times 8
pi@raspberrypi:/tmp $ ./a.out
111111111111111111111111111111111111111111
42 times 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...