C ++中的后缀计算仅在某些时候产生正确的答案

时间:2015-11-07 18:05:10

标签: c++

我目前正在学习数据结构,我正在尝试用C ++编写一个程序,该程序使用数组作为模拟堆栈。代码应该像这样工作:

用户输入Postfix表达式。表达式从左到右阅读。无论何时读取数字,它都会“弹出”到模拟堆栈上。当读取操作数时,模拟堆栈中的前两个数字被“弹出”,操作数用这些数字执行计算,并且得到的答案被“推”回到模拟堆栈上。该过程继续,直到模拟堆栈中只剩下一个数字。这个数字是Postfix表达式的答案,它在屏幕上向用户读出。

我的代码(下面)大部分都在工作。但是,如果我的模拟堆栈中的某个值大于或等于128,则该数字似乎存储不正确(例如,+ 128变为-128)。

我做错了什么?这与我在calc函数中返回答案的方式有什么关系吗?具体来说,这行代码:return answer;

非常感谢任何帮助或提示。

    #include <string>
    #include <iostream>
    using namespace std;

    // Define the size of the stack:
    #define SIZE 50

    // Global variable declarations:
    char stack[SIZE];
    int top = -1; // The top of the array

    // Function for PUSHING operands onto the stack:
    void push(char elem)
    {
        top++;
        stack[top] = elem;
    //    cout << elem << " TESTING PUSH OUTPUT\n"; // TESTING
    }

    // Function for POPPING operands from the stack:
    char pop()
    {
        char answer;
        answer = stack[top];
        top--;
    //    cout << top << " TESTING WHAT'S POPPED\n"; // TESTING
        return (answer);
    }

    // Function for CALCULATING two popped numbers:
    double calc(char op)
    {
        int num1, num2, answer;

        // Pop two numbers from the stack:
        num1 = pop(); 

        num2 = pop(); // put the second popped number into 'num2'

        // Calculate the two popped numbers:
        switch (op)
        {
        case '*':
            answer = num2 * num1;
            break;
        case '/':
            answer = num2 / num1;
            break;
        case '+':
            answer = num2 + num1;
            break;
        case '-':
            answer = num2 - num1;
            break;
        default:
            cout << "Invalid expression!";
        }

        // Push the result of the calculation back onto the stack:
        push(answer);

        return answer;

    }

    // The main program, which takes in the expression:
    int main ()
    {
        string postfix;

        int solution;

        cout << "Please enter a Postfix expression, with operators and operands separated by spaces and/or commas (e.g: 3 7 5 + 2 - * 16 4 + 10 / /): \n";
        getline(cin,postfix);

        // If the User's Postfix expression begins with an operator, then throw up an error message:
        if (postfix.find('/') == 0 || postfix.find('*') == 0 || postfix.find('+') == 0 || postfix.find('-') == 0)
        {
            cout << "Sorry, that's an invalid Postfix expression, and it can't be evaluated.";

            return 0;

        }

        // FOR loop to read the Postfix expression:
        for(unsigned int i = 0; i < postfix.length(); i++)
        {

            // If the value is a space or a comma, move on to the next value:
            if(postfix[i] == ' ' || postfix[i] == ',') 
            {
                continue;
            } // End IF

            // If the value is a number, extract it, and continue reading and extracting the next value until it is NOT a number:
            else if(isalnum(postfix[i]))
            {

                int operand = 0;

                while(i < postfix.length() && isalnum(postfix[i]))
                {
                    // For multi-digit numbers, multiply the initial extracted number by 10 to move it into the 'tens' column, then add the next number to the initial number.
                    // Continue doing this until the next value is NOT a number
                    operand = (operand * 10) + (postfix[i] - '0');
                    i++;
                } // End WHILE

                // When WHILE exits, 'i' will be non-numeric, of the 'end of the string'. Decrement 'i', because it will be incremented in the FOR loop as longs as the FOR condition is true
                // (Stops 'i' from being incremented twice)
                i--;

                // Push the operand onto the stack:
                push(operand);
            } // End ELSE IF

            // If the value is an operator, run the calculation function:
            else
            {
                calc(postfix[i]);
            } // End ELSE

        } // End FOR

        solution = pop(); // put the solution of the equation into 'answer'

        cout << "The solution to the Postfix expression is: " << solution;

    }

3 个答案:

答案 0 :(得分:2)

operand的类型为int,而push的格式为char

因为在大多数计算机上sizeof(int) > sizeof(char),如果尝试将operand存储在较小的数据类型char中,sizeof(int) == 4的值可能会被截断。

例如,假设charsizeof(char) == 1,一个字节是8位。现在,如果只设置了8个 th 位(从0开始),0x100将无法保存该信息,并且值0x00将被截断为{ {1}}。

要解决此问题,请使堆栈处理int s或将operand定义为char

答案 1 :(得分:1)

您只需要模拟stack类型int而不是char(以及其他相关更改)。

答案 2 :(得分:1)

您的堆栈是char类型,通常限制为-128到127.尝试unsigned char,它可能是0到255.如果您需要更大的堆栈值,那么您将使它成为一个int或其他数组大。