Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
 
tyreu
Заблокирован
#1

Вычислить значение произвольного выражения, представленного в обратной польской записи - C (СИ)

13.09.2014, 11:32. Просмотров 1332. Ответов 21
Метки нет (Все метки)

Здравствуйте. Помогите с прогой пожалуйста.

Дано арифметическое выражение длиной до 30 символов, заканчивающееся знаком равенства. Выражение содержит знаки операции +, -, *, / и представлено в обратной польской записи. Если это операнд, то записать его в стек; если это операция, то извлечь два элемента из стека, выполнить математическую операцию и занести результат в стек. Вычислить значение выражения, используя стек операндов. Язык программирования С++. Помогите пожалуйста

Пример: 345+2*63/-+ = 19

Прогу сделал, но почему-то выводит не тот результат.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <stdio.h>
#include <iostream>
using namespace std;
 
int Chislo ( char text [], int *i )
{
    int c = 0;
    while ( text [*i] >= '0' && text [*i] <= '9999' )
    {
        c = c * 10000 + ( text [*i] - '0' );
        (*i)++;
    }
    return c;
}
 
int main()
{
    char text [80];
    int i;
    float opd [3];
    char opc [3];
    int pr [3];
    int j = -1;
    cout << "Vvedite verazenie: ";
    gets ( text );
    i = -1;
    do
    {
        i++;
        opd [++j] = Chislo ( text, &i );
        opc [j] = text [i];
        switch ( text [i] )
        {
            case '+':
            case '-': pr [j] = 1; break;
            case '*':
            case '/': pr [j] = 2; break;
            case ' ': pr [j] = 0;
        }
        while ( j > 0 && pr [j] <= pr [j-1])
        {
            switch ( opc [j-1])
            {
                case '+': opd [j-1] = opd [j-1] + opd [j]; break;
                case '-': opd [j-1] = opd [j-1] - opd [j]; break;
                case '*': opd [j-1] = opd [j-1] * opd [j]; break;
                case '/': opd [j-1] = opd [j-1] / opd [j];
            }
            opd [j-1] = opc [j];
            pr [j-1] = pr [j];
            j = j-1;
        }
    }
    while ( text [i] != ' ');
    cout << "Rezultat: " << opd [0] << endl;
 
    system ( "pause" );
    return 0;
}
Проверьте, пожалуйста. Но мне надо, чтобы числа были максимум 4-значные и массив строки был динамический. Спасибо, заранее
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.09.2014, 11:32
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Вычислить значение произвольного выражения, представленного в обратной польской записи (C (СИ)):

Вычислить значение произвольного выражения, представленного в обратной польской записи
Вычислить значение произвольного выражения, представленного в обратной польской...

K&R калькулятор обратной польской записи
В известной книге есть пример калькулятора в обратной польской записи. Проблема...

Странный результат вычисления строки в обратной польской записи
Ввожу строку, преобразовывает ок, но считает как-то криво Например 100+2 =...

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

Дано выражение a*b/(a+b). Организовать вычисление этого выражения, используя алгоритм польской записи. Применить системн
Дано выражение a*b/(a+b). Организовать вычисление этого выражения, используя...

K&R, глава 4.3. калькулятор с обратной польской нотацией.
Добрый вечер. Я застопорился с примером из книги &quot;C Programming Language&quot;, 2е...

21
Renji
2123 / 1482 / 452
Регистрация: 05.06.2014
Сообщений: 4,320
13.09.2014, 12:59 #2
Прогу сделал, но почему-то выводит не тот результат.
А при компиляции выдаются какие-то предупреждения о некорректности '9999' (должно быть в двойных кавычках и работать все равно не будет). Но ведь варнинги компилятора только ламеры читают.
0
BlackIce
310 / 172 / 73
Регистрация: 18.01.2014
Сообщений: 387
13.09.2014, 13:28 #3
Цитата Сообщение от tyreu Посмотреть сообщение
Пример: 345+2*63/-+ = 19
Это фигня -- сначала в стек заносится 345, потом встречается оператор "+", для выполнения которого требуется извлечь из стека два операнда, а в вашем примере только один, т.е. данное выражение содержит ошибку.

Давайте определим корректное выражение, как строку, содержащую набор операндов и операторов разделенных пробельными символами, например "1 2 + 4 × 3 +" -- это корректное выражение.

Почему бы не использовать шаблонный класс std::stack для работы со стеком? К примеру, вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stack>
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
 
int main() {
    bool run = true;
    stack<double> s;
    while (run) {
        string op;
        cin >> op;
        istringstream iss(op);
        double val;
        if (iss >> val) {
            s.push(val);
        } else {
            val = s.top();
            s.pop();
            if (op == "+") {
                val += s.top();
                s.pop();
                s.push(val);
            } else if (op == "-") {
                val -= s.top();
                s.pop();
                s.push(val);
            } else if (op == "*") {
                val *= s.top();
                s.pop();
                s.push(val);
            } else if (op == "/") {
                val /= s.top();
                s.pop();
                s.push(val);
            } else if (op == "=") {
                cout << val << endl;
                run = false;
            } else {
                cout << "error" << endl;
                run = false;
            }
        }
    }
}
Пример работы:
Вычислить значение произвольного выражения, представленного в обратной польской записи
Замечу, что вышеприведенная программа имеет множество недостатков, к примеру, при получении оператора и вычислении результата не проверяется то, что стек может быть пуст. Но она работает на заведомо корректных выражениях -- можете использовать ее, как заготовку для своей рабочей программы.
1
tyreu
Заблокирован
13.09.2014, 14:55  [ТС] #4
Извините, но препод запретил пользоваться ООП.
C++
1
2
3
4
5
6
if (iss >> val) {
 cout << val << endl;
                run = false;
            } else {
                cout << "error" << endl;
                run = false;
это надо заменить на стандартные.
0
zss
Модератор
Эксперт С++
6950 / 6512 / 4133
Регистрация: 18.12.2011
Сообщений: 17,175
Завершенные тесты: 1
13.09.2014, 15:00 #5
Цитата Сообщение от tyreu Посмотреть сообщение
препод запретил пользоваться ООП
А почему тогда cout можно.
Это тоже объект, и тоже из STL!
0
tyreu
Заблокирован
13.09.2014, 15:02  [ТС] #6
Цитата Сообщение от zss Посмотреть сообщение
А почему тогда cout можно.
Это тоже объект, и тоже из STL!
нельзя, я его тоже указал.
0
zss
Модератор
Эксперт С++
6950 / 6512 / 4133
Регистрация: 18.12.2011
Сообщений: 17,175
Завершенные тесты: 1
13.09.2014, 15:06 #7
Тогда переношу Вашу тему в раздел Си.
0
tyreu
Заблокирован
13.09.2014, 15:10  [ТС] #8
Цитата Сообщение от zss Посмотреть сообщение
Тогда переношу Вашу тему в раздел Си.
а че?

Добавлено через 22 секунды
Оставьте тут, пусть кто-то мне эти строчки переделает. Автор кода, например
0
zss
Модератор
Эксперт С++
6950 / 6512 / 4133
Регистрация: 18.12.2011
Сообщений: 17,175
Завершенные тесты: 1
13.09.2014, 15:21 #9
Цитата Сообщение от tyreu Посмотреть сообщение
пусть кто-то мне эти строчки переделает
Проще написать заново.
0
tyreu
Заблокирован
13.09.2014, 15:23  [ТС] #10
Вообще то нет. Вот как cout можно на printf заменить, так и остальное. Кто знает, может сделать за полминуты. Сделайте пожалуйста.
0
BlackIce
310 / 172 / 73
Регистрация: 18.01.2014
Сообщений: 387
13.09.2014, 15:23 #11
Цитата Сообщение от tyreu Посмотреть сообщение
Извините, но препод запретил пользоваться ООП.
Об этом надо предупреждать заранее или сразу делать сообщение в разделе о Си, а не С++.
Цитата Сообщение от tyreu Посмотреть сообщение
надо заменить на стандартные.
STL -- это тоже стандарт.
Ну ладно, вот так:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <cstdio>
 
int main() {
    bool run = true;
    char op[666];
    double stack[666];
    int top = -1;
    while (run) {
        scanf("%s", op);
        double val;
        if (sscanf(op, "%lf", &val) == 1) {
            stack[++top] = val;
        } else {
            val = stack[top--];
            if (op[1] == '\0') {
                switch (op[0]) {
                case '+':
                    stack[top] += val;
                    break;
                case '-':
                    stack[top] -= val;
                    break;
                case '*':
                    stack[top] *= val;
                    break;
                case '/':
                    stack[top] /= val;
                    break;
                case '=':
                    printf("%f\n", val);
                    run = false;
                    break;
                default:
                    printf("error\n");
                    run = false;
                    break;
                }
            } else {
                printf("error\n");
                run = false;
            }
        }
    }
}
Недостатки ровно те же, что и в предыдущей программе: неверный ввод может привести к неопределенному поведению. Операнды и операторы должны быть разделены пробелами. В общем, работайте, чтобы довести это до ума.
0
tyreu
Заблокирован
13.09.2014, 15:37  [ТС] #12
Спасибо огромное.

Добавлено через 11 минут
Цитата Сообщение от BlackIce Посмотреть сообщение
Недостатки ровно те же, что и в предыдущей программе: неверный ввод может привести к неопределенному поведению. Операнды и операторы должны быть разделены пробелами. В общем, работайте, чтобы довести это до ума.
нихера не решает. в конце выдает error при любом раскладе. исправьте.
0
BlackIce
310 / 172 / 73
Регистрация: 18.01.2014
Сообщений: 387
13.09.2014, 15:44 #13
Цитата Сообщение от tyreu Посмотреть сообщение
нихера не решает. в конце выдает error при любом раскладе.
У меня все работает, что я делаю не так:
Вычислить значение произвольного выражения, представленного в обратной польской записи
Цитата Сообщение от tyreu Посмотреть сообщение
исправьте.
Приказы и распоряжения будете раздавать, когда станете большим начальником
0
tyreu
Заблокирован
13.09.2014, 23:05  [ТС] #14
BlackIce, я собираюсь на VS Professional 2013 и у меня выдает всегда "error"
0
BlackIce
310 / 172 / 73
Регистрация: 18.01.2014
Сообщений: 387
13.09.2014, 23:15 #15
Цитата Сообщение от tyreu Посмотреть сообщение
я собираюсь на VS Professional 2013
Вы собираетесь? Вы есть программа? Или вы куда-то собираетесь?

Цитата Сообщение от tyreu Посмотреть сообщение
и у меня выдает всегда "error"
Пример входных данных и скриншот неверной работы. <censored>, для вас написали пример работающей при определенных условиях программы, показали скриншоты ее работы, вы же только ноете, что не работает. Посмотрите еще раз скриншоты в моих сообщениях, там в заголовке окон <censored> или таки VS2013?

Неужели так трудно написать: ввожу то-то то-то, ожидаю увидеть то-то то-то, вместо этого вижу <censored>?
0
tyreu
Заблокирован
13.09.2014, 23:17  [ТС] #16
BlackIce, ну ты понимаешь, что я ввожу пример, а он выдает еррор? как мне быть?
0
BlackIce
310 / 172 / 73
Регистрация: 18.01.2014
Сообщений: 387
13.09.2014, 23:19 #17
Цитата Сообщение от tyreu Посмотреть сообщение
ну ты понимаешь, что я ввожу пример, а он выдает еррор? как мне быть?
Повторяю для прапорщиков:
Цитата Сообщение от BlackIce Посмотреть сообщение
Пример входных данных и скриншот неверной работы.
0
Вованя
137 / 134 / 63
Регистрация: 20.02.2014
Сообщений: 478
Завершенные тесты: 1
13.09.2014, 23:20 #18
tyreu,

Не по теме:

Может зря в программирование пошел?

0
tyreu
Заблокирован
14.09.2014, 11:37  [ТС] #19
Цитата Сообщение от Вованя Посмотреть сообщение
Может зря в программирование пошел?
Не зря, но мне нравится всё, кроме с++, а учить приходится, но вообще не идёт.

Добавлено через 12 минут
Вычислить значение произвольного выражения, представленного в обратной польской записи
Вот вам скриншот и входные данные
0
BlackIce
310 / 172 / 73
Регистрация: 18.01.2014
Сообщений: 387
14.09.2014, 11:54 #20
Лучший ответ Сообщение было отмечено tyreu как решение

Решение

Цитата Сообщение от tyreu Посмотреть сообщение
Вот вам скриншот и входные данные
Создал проект, тупо скопировал в него код из сообщения, запустил:
Вычислить значение произвольного выражения, представленного в обратной польской записи
При компиляции куча варнингов, но работает же.

Короче, сдаюсь, не могу понять, почему у вас не работает. Если очень нужно, то могу через TeamViewer зайти и посмотреть, пишите в личку.
0
14.09.2014, 11:54
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.09.2014, 11:54
Привет! Вот еще темы с решениями:

Перевод числа представленного в экспоненциальной записи в двоичную систему
Всем привет! Столкнулся с такой задачкой: Нужно написать программу для перевода...

Калькулятор основанный на польской записи (учебник Ритчи)
Добрый день! Изучаю Си по книге Ритчи. В одном из разделов(4.3) есть такой...

Написать программу построения польской имперсной записи
Здравствуйте, ув. программисты, помогите написать программу построения польской...

Вычислить значение выражения
Помогите найти ошибку. Числа генерируются с помощью ЛКГ. Нужно получить &quot;С&quot; -...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru