рассчитать сумму всех чисел, присутствующих в строке - PullRequest
1 голос
/ 11 февраля 2020

Я решаю эту проблему:

Если задана строка str, содержащая alphanumeri c символов, вычислить сумму всех чисел, присутствующих в строке.

Input:

Первая строка ввода содержит целое число T, обозначающее количество тестовых случаев. Затем следуют тесты T. Каждый тестовый пример содержит строку, содержащую буквы алфавита c.

Вывод:

Вывести сумму всех чисел, присутствующих в строке.

Ограничения:

1 <= T <= 10 <sup>5

1 <= длина строки <= 10 <sup>5

Пример: Вход:

4
1abc23
geeks4geeks
1abc2x30yz67
123abc

Выход:

24
4
100
123

I пришли к следующему решению:

#include <stdio.h>
#include <string.h>
int main() {
    //code
int t,j;
char a[100000];
scanf("%d",&t);
 while(t--)
 {   
    int sum=0,rev=0,i=0,l;
    scanf("%s",a); 
    l=strlen(a);
    for(i=0;i<l;i++) 
    {
          if (isdigit(a[i])){
             while(isdigit(a[i])){
               rev = rev *10 + (a[i]-48);
               i++;
             }
          }
        sum+=rev;
        rev=0;        
    }
    printf("%d\n",sum);
 }
    return 0;
}

Этот код работает нормально. НО если условие прекращения l oop изменяется с i на a [i]! = '\ 0' , то код не работает. Почему?

Ответы [ 3 ]

2 голосов
/ 11 февраля 2020

Я бы л oop задом наперед. Нет вложенных циклов. Просто возьмите показатель 10 с при перемещении влево

У вас есть длина строки, поэтому нет никаких оснований проверять NUL-символ самостоятельно

(непроверенный код, но показывает общую идею )

#include <math.h>


l=strlen(a);
int exp; 
exp = 0;
for(i = l-1; i >= 0; i--) 
{
      if (isdigit(a[i])) {
           rev = a[i]-48;  // there are better ways to parse characters to int 
           rev = (int) pow(10, exp) * rev;
           sum += rev;  // only add when you see a digit 
      } else { exp = -1; } // reset back to 10^0 = 1 on next loop 

    exp++;
}

Другие решения включают использование регулярного выражения для разбиения строки на все символы, отличные от di git, затем l oop и суммирование всех чисел

2 голосов
/ 11 февраля 2020

Вам также придется изменить логи c в вашем времени l oop, если вы хотите изменить sh в вашем состоянии для l oop, поскольку вполне возможно, что число существует в конце Строка также, как в одном из ваших входных данных 1abc2x30yz67. Таким образом, правильный код будет выглядеть так:

Фрагмент:

 for(i=0;a[i]!='\0';i++) 
    {
          if (isdigit(a[i])){
             while(a[i]!='\0' && isdigit(a[i])){ // this line needs check as well
               rev = rev *10 + (a[i]-48);
               i++;
             }
          }
        sum+=rev;
        rev=0;        
    }

При дальнейшей проверке вам необходимо условие i в любом случае в вашем состоянии l oop.

while(i < l && isdigit(a[i])){

Обновление № 1:

Точнее, l oop while(isdigit(a[i])){ сохраняет идти до конца строки. Хотя это не вызывает проблем в самом l oop, потому что \0 не является di git, но a[i] != '\0' в условии for l oop позволяет вам получить доступ к чему-либо за пределами длины строки потому что мы продвигаемся еще на 1 позицию из-за i++ в for для l oop, тогда как мы уже достигли конца строки во внутренней части, в то время как l oop.

Update # 2:

Вам также нужна дополнительная проверка a[i] == '\0' для уменьшения i.

#include <stdio.h>
#include <string.h>
int main() {
    //code
int t,j;
char a[100000];
scanf("%d",&t);
 while(t--)
 {   
    int sum=0,rev=0,i=0,l;
    scanf("%s",a); 
    l=strlen(a);
    for(i=0;a[i]!='\0';i++) 
    {
          if (isdigit(a[i])){
             while(a[i] != '\0' && isdigit(a[i])){ // this line needs check as well
               rev = rev *10 + (a[i]-48);
               i++;
             }
          }

        if(a[i] == '\0') i--; // to correctly map the last index in the for loop condition
        sum+=rev;
        rev=0;        
    }
    printf("%d\n",sum);
 }
    return 0;
}

Обновление № 3:

Вы можете полностью избежать пока l oop, как показано ниже:

#include <stdio.h>
#include <string.h>
int main() {
    //code
int t,j;
char a[100005];
scanf("%d",&t);
 while(t--)
 {   
    int sum=0,rev=0,i=0,l;
    scanf("%s",a); 
    l=strlen(a);
    for(i=0;i<l;i++) {
      if (isdigit(a[i])){
         rev = rev * 10 + (a[i]-48);
      }else{
        sum += rev;
        rev = 0;
      }
    }
    printf("%d\n",sum + rev); // to also add last rev we captured
 }
    return 0;
}
0 голосов
/ 11 февраля 2020

В других ответах указаны правильные условия l oop для обеспечения правильной работы вашей программы.

Если вам разрешено использовать библиотечные функции, отличные от isdigit, я бы порекомендовал использовать strtol с параметром EndPtr (выходной параметр, который указывает на символ в строке, который заставил strtol остановить сканирование номера):

char str[] = "1abc23def5678ikl";

int main()
{
    char *pStop = str;
    int n, accum = 0;
    size_t len = strlen(str);

    do
    {
        n = strtol(pStop, &pStop, 10);
        pStop++;
        if(n)
        {
            printf("%d\n", n);
            accum += n;
        }
    }
    while(pStop < &str[len]);

    printf("Total read: %d\n", accum);

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...