1 Востаннє редагувалося Skyzerks Synx (12.11.2014 23:06:21)

Тема: Проблема з обчисленням в С++

Вот ми маємо таку задачку:
вводимо якісь цифри + знаки арифметичних операцій(тільки + і -): 5+4-7+10-3
і щоб результаті воно розпізнавало ці знаки операції і програма сама їх додавала, тобто:
5+4-7+10-3=9.

#include "stdafx.h"
#include <iostream>
using namespace std;
#include <stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_CTYPE, "rus");
    cout<<"Введите строку: ";
    char a[100], *p, *znak1="+", *znak2="-";
    int i=0, summa = 0;
    cin>>a;
    p=strtok(a, znak1); //умова для "+"
    while (p)
    {
        int b = atoi(p);
        if(*znak1)
        {
            summa+=b;
            p=strtok(NULL, znak1);
        }
        else                         //<- ввів умову для "-", але як саме задати ще один 
        {                               //strtok якраз  для цього знака не представляю
            summa-=b;
            p=strtok(NULL, znak2);
        }
    }
    cout<<a<<" = "<<summa<<'\n';
    system("pause");
    return 0;
}
P.S.

При виводі некоректно виводить символи перед "=", але на даний момент це не важливо

2

Re: Проблема з обчисленням в С++

Skyzerks Synx написав:

        else                         //<- ввів умову для "-", але як саме задати ще один
        {                               //strtok якраз  для цього знака не представляю
            summa-=b;
            p=strtok(NULL, znak2);
        }

Ця умова ніколи не виконується

Подякували: koala1

3

Re: Проблема з обчисленням в С++

Ця умова ніколи не виконується

там помилково скинув недороблений новий варіант програми.
Ось тут перероблений варіант:

#include "stdafx.h"
#include <iostream>
using namespace std;
#include <stdio.h>
#include <string.h>
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_CTYPE, "rus");
    cout<<"Введите строку: ";
    char a[100], *p, *znak="+-";
    int i=0, summa = 0;
    cin>>a;
    p=strtok(a, znak);
    while (p)
    {
        int b = atoi(p);
        if(znak="+") summa+=b;    //<- некоректна умова
        else summa-=b;
        p=strtok(NULL, znak);
    }
    cout<<a<<" = "<<summa<<'\n';
    system("pause");
    return 0;
}

але тепер виникла проблема з тим щоб виловити одне з двох станів "znak", щоб застосувати певні дії до числа після цього знака

4

Re: Проблема з обчисленням в С++

strtok вирізає з рядка шматок, замінюючи розділювач (у вашому випадку + або -) на нульовий символ. А це явно не те, що вам потрібно. Зверніть увагу на strcspn та strpbrk; або розберіть рядок ручками по символу, початківцям краще написати пару велосипедів, тоді буде зрозуміло, нащо потрібні ті функції і як вони працюють.

простий розв'язок
    int i=0, summa = 0;
    while(cin>>i)
      summa+=i;
    cout<<summa<<'\n';
Подякували: Skyzerks Synx1

5 Востаннє редагувалося Skyzerks Synx (08.11.2014 15:18:06)

Re: Проблема з обчисленням в С++

koala написав:

strtok вирізає з рядка шматок, замінюючи розділювач (у вашому випадку + або -) на нульовий символ. А це явно не те, що вам потрібно. Зверніть увагу на strcspn та strpbrk; або розберіть рядок ручками по символу, початківцям краще написати пару велосипедів, тоді буде зрозуміло, нащо потрібні ті функції і як вони працюють.

простий розв'язок
    int i=0, summa = 0;
    while(cin>>i)
      summa+=i;
    cout<<summa<<'\n';

Пробував писати код для присвоєння знака на початок кожного числа:

int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_CTYPE, "rus");
    cout<<"Введите строку: ";
    char a[100], *p="", b[2], *znak="+-";
    int i=0, summa = 0;
    cin>>a;
    for(;a[i]!='\0'; i++)
    {
        b[0]=a[i];
        strcat(p, b);
        if(a[i]='+') 
        {
            summa+=atoi(p);
            p="";
        }
        if(a[i]='-')
        {
            summa+=atoi(p);
            p="";
            strcat(p, "-");
        }
    }
    cout<<a<<" = "<<summa<<'\n';
    system("pause");
    return 0;
}

Но було б все добре, якби не помилка в коді, яку я нажаль не бачу :(

6

Re: Проблема з обчисленням в С++

напевно помилка в

strcat(p, "-");

але закоментувавши цю частину, все одно вибиває помилки.

7

Re: Проблема з обчисленням в С++

if(a[i]='+')

це не умова. Це присвоювання

a[i]='+'

після якого його значення (тобто '+') порівнюється із нулем, і якщо не нуль (а очевидно, що не нуль) виконується основна гілка if.

8 Востаннє редагувалося Betterthanyou (08.11.2014 16:44:12)

Re: Проблема з обчисленням в С++

Я написав код подивіться можливо це те що ви хотіли, цей код обробляє рядок по символьно

#include <iostream>
using namespace std;

int main()
{
    setlocale(LC_CTYPE, "rus");
    cout << "Введите строку: ";
    char arr[100], num[10], znak = '+';
    int summa = 0;
    cin.getline(arr, 100);
    for (int i = 0, j = 0; i < strlen(arr); i++)
    {
        switch (arr[i])
        {
        case '+':if (znak == '+') summa += atoi(num); else summa -= atoi(num);
            j = 0, num[0] = '\0', znak = '+'; break;

        case '-':if (znak == '+') summa += atoi(num); else summa -= atoi(num);
            j = 0, num[0] = '\0', znak = '-'; break;
        default:
            num[j++] = arr[i],
                num[j] = '\0';
            break;
        }
    }
    if (znak == '+') 
        summa += atoi(num);
    else 
        summa -= atoi(num);
    cout << arr << " = " << summa << endl;
    system("pause");
    return 0;
}

9

Re: Проблема з обчисленням в С++

        case '+':if (znak == '+') summa += atoi(num); else summa -= atoi(num);
            j = 0, num[0] = '\0', znak = '+'; break;
 
        case '-':if (znak == '+') summa += atoi(num); else summa -= atoi(num);
            j = 0, num[0] = '\0', znak = '-'; break;

*CRAZY*  ололо на башорк гівнокод  *CRAZY*

Хіба не непомітно, що єдина різниця між цими варіантами - це "znak = '-';", причому + та - там точно такі ж, як і в case, тобто можуть бути замінені на arr[ i ]?

10

Re: Проблема з обчисленням в С++

koala написав:

Хіба не непомітно, що єдина різниця між цими варіантами - це "znak = '-';", причому + та - там точно такі ж, як і в case, тобто можуть бути замінені на arr[ i ]?

Те що код не дуже я сам розумію, znak запам'ятовує який був знак перед цім тому arr[ i ] там точно бути не може, а от як справити повторення коду я не знаю хотів функцію зробить але прийдеться їй багато чого передавати

11 Востаннє редагувалося koala (08.11.2014 17:31:24)

Re: Проблема з обчисленням в С++

Ваш switch має виглядати так, ітерація 1: (трохи привів код до читаємого стану)

switch (arr[i])
{
  case '+' : //fallthrough 
  case '-' : 
    if (znak == '+') 
      summa += atoi(num);
    else 
      summa -= atoi(num);
    j = 0;
    num[0] = '\0';
    znak = arr[i]; 
  break;
  default :
    num[j++] = arr[i],
                num[j] = '\0';
  break;
}

Тепер у нас тільки 2 гілки, тому бажано зробити ітерацію 2:

if( strchr( "+-", arr[ i ] ) )
{
  if ( arr[ i ] == '+' ) 
    summa += atoi(num); 
  else 
    summa -= atoi(num);
  j = 0;
  num[0] = '\0';
}
else
{
  num[j++] = arr[i];
  num[j] = '\0';
}

Можна і далі покращувати (наприклад, ставити '\0' в num тільки один раз, перед atoi), але закінчиться це моїм спойлером.

Подякували: Betterthanyou1

12 Востаннє редагувалося Betterthanyou (08.11.2014 18:10:26)

Re: Проблема з обчисленням в С++

koala написав:

Тепер у нас тільки 2 гілки, тому бажано зробити ітерацію 2:

if( strchr( "+-", arr[ i ] ) )
{
  if ( arr[ i ] == '+' ) 
    summa += atoi(num); 
  else 
    summa -= atoi(num);
  j = 0;
  num[0] = '\0';
}
else
{
  num[j++] = arr[i];
  num[j] = '\0';
}

щось тут я не зрозумів до чого цей код якщо його поставити в цикл то він не працює наприклад

for (int i = 0, j = 0; i < strlen(arr); i++)
    {
        if (strchr("+-", arr[i]))
        {
            if (arr[i] == '+')
                summa += atoi(num);
            else
                summa -= atoi(num);
            j = 0;
            num[0] = '\0';
        }
        else
        {
            num[j++] = arr[i];
            num[j] = '\0';
        }
    }

1+1 відповідь 1

13

Re: Проблема з обчисленням в С++

koala написав:
if(a[i]='+')

це не умова. Це присвоювання

a[i]='+'

після якого його значення (тобто '+') порівнюється із нулем, і якщо не нуль (а очевидно, що не нуль) виконується основна гілка if.

Ну я собі ось та роздумував:
вводимо це все діло
воно зчитує до першого знаку операції
додає до summa складене число, а відповідно до знака дальше присвоює на початок нового числа після знаку операції, значення яке відповідає дії над ним
тобто якщо є 25-4, це:
25 - сформували число, присвоїли до суми, а саму змінну під неї обнулили
зчитали знак -, присвоїли до символьної змінної "-4" і перетворили в число, просумували, обнулили символьну змінну.
Хотілось би знати чи такий варіант працював би.

14

Re: Проблема з обчисленням в С++

Skyzerks Synx написав:
koala написав:
if(a[i]='+')

це не умова. Це присвоювання

a[i]='+'

після якого його значення (тобто '+') порівнюється із нулем, і якщо не нуль (а очевидно, що не нуль) виконується основна гілка if.

Ну я собі ось та роздумував:
вводимо це все діло
воно зчитує до першого знаку операції
додає до summa складене число, а відповідно до знака дальше присвоює на початок нового числа після знаку операції, значення яке відповідає дії над ним
тобто якщо є 25-4, це:
25 - сформували число, присвоїли до суми, а саму змінну під неї обнулили
зчитали знак -, присвоїли до символьної змінної "-4" і перетворили в число, просумували, обнулили символьну змінну.
Хотілось би знати чи такий варіант працював би.

Ви під мій спойлер заглядали?

15 Востаннє редагувалося koala (08.11.2014 18:38:13)

Re: Проблема з обчисленням в С++

Betterthanyou написав:
koala написав:

Тепер у нас тільки 2 гілки, тому бажано зробити ітерацію 2:

...

щось тут я не зрозумів до чого цей код якщо його поставити в цикл то він не працює наприклад

...

1+1 відповідь 1

http://ideone.com/6fNjh3

Success    time: 0 memory: 5048 signal:0
Введите строку: 1+1 = 2

16

Re: Проблема з обчисленням в С++

koala написав:
Betterthanyou написав:
koala написав:

Тепер у нас тільки 2 гілки, тому бажано зробити ітерацію 2:

...

щось тут я не зрозумів до чого цей код якщо його поставити в цикл то він не працює наприклад

...

1+1 відповідь 1

http://ideone.com/6fNjh3

Success    time: 0 memory: 5048 signal:0
Введите строку: 1+1 = 2

ну ОК йдем далі 3+3-5 ваш код дає результат 5

17

Re: Проблема з обчисленням в С++

Підтверджую баг. Переоптимізував :)

        if (strchr("+-", arr[i]))
        {
            if (znak == '+')
                summa += atoi(num);
            else
                summa -= atoi(num);
            j = 0;
            num[0] = '\0';
            znak = arr[i];
        }
        else
        {
            num[j++] = arr[i];
            num[j] = '\0';
        }

http://ideone.com/6fNjh3
Так краще?

18 Востаннє редагувалося Skyzerks Synx (08.11.2014 19:14:12)

Re: Проблема з обчисленням в С++

koala написав:

Ви під мій спойлер заглядали?

Так, але я такий спосіб використання while бачу вперше.

19 Востаннє редагувалося Betterthanyou (08.11.2014 19:11:33)

Re: Проблема з обчисленням в С++

koala Так вже працює правильно

20

Re: Проблема з обчисленням в С++

Skyzerks Synx написав:
koala написав:

Ви під мій спойлер заглядали?

Так, але я такий спосіб використання while бачу вперше.

Але це якраз такий спосіб виведення який я так довго шукав -
щоб присвоювало змінній значення прямо під час записування в консоль. (ну я таким чином його розумію  :) )