Заблокирован
1

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

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

Author24 — интернет-сервис помощи студентам
Здравствуйте. Помогите с прогой пожалуйста.

Дано арифметическое выражение длиной до 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)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.09.2014, 11:32
Ответы с готовыми решениями:

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

Нужно написать написать программу, которая вычисляет значение выражения в обратной польской записи
Обра́тная по́льская запись (англ. Reverse Polish notation, RPN) — форма записи математических и...

Вычислить значение выражения представленного в обратной польской записи
Здравствуйте! Нужна помощь с заданием по питону. Задание: Арифметическое выражение можно...

Вычислить значение выражения в обратной польской записи с использованием стека
Вычислить значение выражения в обратной польской записи с использованием стека. например 6 2 + = 6...

21
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
13.09.2014, 12:59 2
Прогу сделал, но почему-то выводит не тот результат.
А при компиляции выдаются какие-то предупреждения о некорректности '9999' (должно быть в двойных кавычках и работать все равно не будет). Но ведь варнинги компилятора только ламеры читают.
0
317 / 179 / 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
Заблокирован
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
Модератор
Эксперт С++
13498 / 10752 / 6407
Регистрация: 18.12.2011
Сообщений: 28,692
13.09.2014, 15:00 5
Цитата Сообщение от tyreu Посмотреть сообщение
препод запретил пользоваться ООП
А почему тогда cout можно.
Это тоже объект, и тоже из STL!
0
Заблокирован
13.09.2014, 15:02  [ТС] 6
Цитата Сообщение от zss Посмотреть сообщение
А почему тогда cout можно.
Это тоже объект, и тоже из STL!
нельзя, я его тоже указал.
0
Модератор
Эксперт С++
13498 / 10752 / 6407
Регистрация: 18.12.2011
Сообщений: 28,692
13.09.2014, 15:06 7
Тогда переношу Вашу тему в раздел Си.
0
Заблокирован
13.09.2014, 15:10  [ТС] 8
Цитата Сообщение от zss Посмотреть сообщение
Тогда переношу Вашу тему в раздел Си.
а че?

Добавлено через 22 секунды
Оставьте тут, пусть кто-то мне эти строчки переделает. Автор кода, например
0
Модератор
Эксперт С++
13498 / 10752 / 6407
Регистрация: 18.12.2011
Сообщений: 28,692
13.09.2014, 15:21 9
Цитата Сообщение от tyreu Посмотреть сообщение
пусть кто-то мне эти строчки переделает
Проще написать заново.
0
Заблокирован
13.09.2014, 15:23  [ТС] 10
Вообще то нет. Вот как cout можно на printf заменить, так и остальное. Кто знает, может сделать за полминуты. Сделайте пожалуйста.
0
317 / 179 / 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
Заблокирован
13.09.2014, 15:37  [ТС] 12
Спасибо огромное.

Добавлено через 11 минут
Цитата Сообщение от BlackIce Посмотреть сообщение
Недостатки ровно те же, что и в предыдущей программе: неверный ввод может привести к неопределенному поведению. Операнды и операторы должны быть разделены пробелами. В общем, работайте, чтобы довести это до ума.
нихера не решает. в конце выдает error при любом раскладе. исправьте.
0
317 / 179 / 73
Регистрация: 18.01.2014
Сообщений: 387
13.09.2014, 15:44 13
Цитата Сообщение от tyreu Посмотреть сообщение
нихера не решает. в конце выдает error при любом раскладе.
У меня все работает, что я делаю не так:
Вычислить значение произвольного выражения, представленного в обратной польской записи

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

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

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

Не по теме:

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

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

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

Вот вам скриншот и входные данные
0
317 / 179 / 73
Регистрация: 18.01.2014
Сообщений: 387
14.09.2014, 11:54 20
Лучший ответ Сообщение было отмечено tyreu как решение

Решение

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

При компиляции куча варнингов, но работает же.

Короче, сдаюсь, не могу понять, почему у вас не работает. Если очень нужно, то могу через TeamViewer зайти и посмотреть, пишите в личку.
0
14.09.2014, 11:54
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.09.2014, 11:54
Помогаю со студенческими работами здесь

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

Калькулятор считающий выражения обратной польской записи из файла
Здравствуйте! У меня вот такое задание &quot;Напишите программу, вычисляющую выражение в обратной...

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

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru