Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.06.2022, 13:21   #1
KostyaS29
Новичок
Джуниор
 
Регистрация: 12.06.2022
Сообщений: 2
По умолчанию Найти ошибку в преобразовании строки в обратную польскую запись

Пытаюсь написать программу, которая преобразует входную строку в обратную польскую запись, использую алгоритм сортировочной станции. Если во входной строке нет скобок, то преобразование происходит правильно. Но с появлением скобок преобразование происходит неверно. Не могу понять в чем ошибка. Подскажите пожалуйста.
Код:
#include <iostream>
#include <string>
#include <stack>

using namespace std;

bool is_letter(char ch)
{
    bool result = false;
    if (ch >= 'A' && ch <= 'Z')
        result = true;
    return result;
}

bool is_number(char ch)
{
    bool result = false;
    if (ch >= '0' && ch <= '9')
        result = true;
    return result;
}

int prioritet(char ch)
{
    int prioritet;
    switch (ch)
    {
    case '*':
    case '/':
        return 4;
    case '-':
    case '+':
        return 3;
    }
    return 0;
}

string Reverse_Polish_Natation(string input_string)
{
    char ch;
    string output_string;
    stack<char> stek_operator;

    for (int i = 0; i < input_string.size(); ++i)
    {
        ch = input_string[i];

        if (is_number(ch) == true)
        {
            while (is_number(ch) == true)
            {
                output_string.push_back(ch);
                i++;
                ch = input_string[i];
            }
            output_string.push_back(' ');
        }
        if (ch == ' ')
        {
            while (input_string[i] == ' ')
                i++;
            i--;
        }
        if (ch == '(')
        {
            stek_operator.push(ch);
        }
        if (ch == ')')
        {
            while (stek_operator.top() == '(')
            {
                output_string.push_back(stek_operator.top());
                stek_operator.pop();
            }
            stek_operator.pop();
            if (is_number(ch) == true)
            {
                output_string.push_back(ch);
            }
        }

        if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
        {
            while (true)
            {
                if (stek_operator.empty() || prioritet(ch) > prioritet(stek_operator.top()))
                {
                    stek_operator.push(ch);
                    break;
                }
                if (prioritet(ch) == prioritet(stek_operator.top()))
                {
                    output_string.push_back(stek_operator.top());
                    output_string.push_back(' ');
                    stek_operator.pop();
                    stek_operator.push(ch);
                    break;
                }
                if (prioritet(ch) < prioritet(stek_operator.top()))
                {
                    output_string.push_back(stek_operator.top());
                    output_string.push_back(' ');
                    stek_operator.pop();
                }
            }
        }
    }
    while (!stek_operator.empty())
    {
        ch = stek_operator.top();
        stek_operator.pop();
        output_string.push_back(ch);
        output_string.push_back(' ');
    }
    cout << output_string << endl;
    return output_string;
}

int main()
{
    string input_string = "(2 + 3) * 4";
    Reverse_Polish_Natation(input_string);
}
KostyaS29 вне форума Ответить с цитированием
Старый 12.06.2022, 13:43   #2
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от KostyaS29 Посмотреть сообщение
Код:
int prioritet(char ch)
{
    int prioritet;
    switch (ch)
    {
    case '*':
    case '/':
        return 4;
    case '-':
    case '+':
        return 3;
    }
    return 0;
}
А при вычислении приоритетов не хотите добавить скобки, раз в стеке они будут лежать как оператор
P.S. При использовании
Код:
switch(ch) {
  case ...
}
по моему этот код будет проще.

Цитата:
Сообщение от KostyaS29 Посмотреть сообщение
Код:
while (is_number(ch) == true)
            {
                output_string.push_back(ch);
                i++;
                ch = input_string[i];
            }
Код:
            while (input_string[i] == ' ')
                i++;
А на конец строки плевать, память длинная, главное все косточки пересчитать. Строки конечно обычно заканчиваются нулевым символом NULL, но строки в классе могут опираться на значение длины и если NULL в конце не будет, то вы уедите за границу строки
Цитата:
Сообщение от KostyaS29 Посмотреть сообщение
Код:
for (int i = 0; i < input_string.size(); ++i)
    {
Основной цикл опирается на значение input_string.size(), а не на NULL в конце строки.

При введении ограничения на длину строки, станет возможным разбор части строки содержащей выражении без ее разбивки/усечения/копирования в подстроку.
macomics вне форума Ответить с цитированием
Старый 12.06.2022, 17:16   #3
KostyaS29
Новичок
Джуниор
 
Регистрация: 12.06.2022
Сообщений: 2
По умолчанию

Исправил те замечания, на которые вы указали, но выходная строка все равно получается не верной
KostyaS29 вне форума Ответить с цитированием
Старый 12.06.2022, 22:00   #4
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Намек с подстроками вы не поняли. Если нашли скобку, то ищите ее закрывающуюся пару и выполняйте рекурсивно/циклически разбор части строки от скобки до скобки. Так приоритеты всех вложенных операторов будут соблюдаться. (A + B) * (C + D) здесь + имеет больший приоритет, чем * потому, что он в скобках. У вас же приоритеты операторов не меняются. (A * B + C) * (D + E) - тут все становится чуть сложнее. Приоритет * в скобках выше чем у + в тех же скобках, а приоритет * между скобок ниже чем у обоих + в скобках.
macomics вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Преобразование в обратную польскую запись с++ sobaka13 Помощь студентам 12 19.05.2021 19:16
Превод из инфиксной в обратную польскую запись Anny_Apple Помощь студентам 0 11.04.2011 19:22
Перевод из инфиксной записи в обратную польскую Anny_Apple Паскаль, Turbo Pascal, PascalABC.NET 1 10.04.2011 20:49
найти ошибку в коде С задача на обратную матрицу Monomah Помощь студентам 0 20.02.2011 17:11
Задача на обратную польскую запись Horknee Помощь студентам 8 11.03.2009 22:09