Странная функция, возвращающая результат - PullRequest
2 голосов
/ 24 мая 2011
float Calculate(const string &query)
{
        std::cout << "Query: " << query << "\n";
        unsigned int size = query.length();
        char stack[70];
        float res;
        int m = 0;

        for (int i = 0; i < size; i++)
        {
                if (query[i] >= '0' && query[i] <= '9')
                {
                        stack[m] = query[i] - '0';
                        m++;
                        continue;
                }

                switch (query[i])
                {
                        case '+':
                        {
                                res = stack[m - 2] + stack[m - 1];
                                break;
                        }
                        case '-':
                        {
                                res = stack[m - 2] - stack[m - 1];
                                break;
                        }
                        case '*':
                        {
                                res = stack[m - 2] * stack[m - 1];
                                break;
                        }
                        case '/':
                        {
                                res = stack[m - 2] / stack[m - 1];
                                break;
                        }
                }

                    stack[m - 2] = res;
                m--;
                cout << "RES: " << res << "\n";
        }

        return res;
}

Он вычисляет обратную польскую запись.

Когда я вызываю что-то вроде: Calculate("11+"), он возвращает правильный результат: 2.

Но, когда я передаю переменную послеполучение строки RPN:

string inputStr;
string outputStr;

cout << "Put exercise\n";
getline(std::cin, inputStr);

outputStr = GetRPN(inputStr);
cout << "Output str :" << outputStr << ":\n";

float res = Calculate(outputStr);
std::cout << res << "\n";

Итак, когда я ввожу строку: 1+1, функция GetRPN возвращает 11+, и я вижу это во втором цикле.Но результат - 0!

Что бы это могло быть?


string GetRPN(string input)
{
    vector <char> operation;
    string outputStr;      //output string, keep RPN
    int stack_count = 0;

    for(int i = 0; i < input.length(); i++)
    {
        if(input[i] >= '0' && input[i] <= '9')
        {
            outputStr += input[i];
        }
        else
        {
            if(operation.empty())
            {
                operation.push_back(input[i]);
                stack_count++;
            }
            else if(operation[stack_count - 1] == '+' || operation[stack_count - 1] == '-')
            {
                operation.push_back(input[i]);
                stack_count++;
            }
            else if ((operation[stack_count - 1] == '*' || operation[stack_count - 1] == '/') && (input[i] == '*' || input[i] == '/'))
            {
                outputStr += operation[stack_count - 1]; // move mark of operation to output str
                operation.pop_back(); // delet last element from vector
                operation.push_back(input[i]);// plus new operation mark to vector
                stack_count++;
            }
            else if (operation[stack_count - 1] == '*' || operation[stack_count - 1] == '/')
            {
                outputStr += input[i];
            }
        }
    }

    for(int i = operation.size(); i >= 0; i--)
    {
        outputStr += operation[i]; // move all operation marks to otput str
    }

    return outputStr;
}

Ответы [ 2 ]

1 голос
/ 24 мая 2011

Ваш цикл здесь

for(int i = operation.size(); i >= 0; i--)
{
    outputStr += operation[i]; // move all operation marks to otput str
}

не имеет никакого смысла.Вы явно пытаетесь получить доступ к вектору с неверным индексом.Доступ к элементу на operation[i] запрещен, когда i равен operation.size().Индекс находится вне диапазона.

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

1 голос
/ 24 мая 2011

Если в вашей строке есть пробелы или непечатаемые символы, вы в конечном итоге сохраните в stack отрицательный индекс, который перезапишет другие элементы в вашем стековом фрейме и может вызвать что-либо.

Вы должны добавить некоторую проверку ошибок в Calculate - коммутатор должен иметь default, который печатает заметное сообщение об ошибке, и вы должны проверить значение m перед доступом к stack[m] или stack[m-2], чтобы сделатьубедитесь, что стек не переполнен и не переполнен (и вы должны напечатать ощутимую ошибку, если он это сделает.) Вы должны быть в состоянии передать ЛЮБУЮ случайную строку в Calculate и сообщить, почему она не является допустимым выражением RPN.

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