【问题标题】:Infix to Postfix to Output (Postfix Calculator) using stacks使用堆栈中缀到后缀到输出(后缀计算器)
【发布时间】:2012-04-05 22:14:49
【问题描述】:

大家好!我是 C++ 新手(在 stackoverflow 中也是如此),我需要各位专家的帮助。

我这里有一个代码,它应该向用户询问中缀表达式,然后将其转换为后缀并输出结果(后缀计算器)。但是,我无法立即将后缀转换为输出,因此一旦显示后缀表达式,它就会在输出真实答案之前再次要求后缀表达式(例如 1 2 + 之后有空格)。

没有错误或警告,但是当我运行程序时,计算机在显示后缀表达式后说“file.exe 已停止工作”。所以程序能够正确地将中缀转换为后缀表达式,但在显示输出时仍然存在一些问题。

#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;

struct node {
    char data;
    node *next;
};

node *top=NULL;
node *bottom=NULL;
node *key;
node *last;
node *before_last;


void push (const char Symbol) {
    key = new node;
    key->data = Symbol;
    key->next = top;
    top = key;
}

void push_for_output (node* &stack, int key) {
    node* newNode = new node;
    newNode->data = key;
    newNode->next = stack;
    stack = newNode;
}

const char pop() {
    if (!top) {
        cout << "Stack underflow\n" << endl;
        return ' ';
    }
    node* key = top;
    top = top->next;
    char ch = key->data;
    delete key;
    return ch;
}

int pop_for_output (node* &stack) {
    int key = stack->data;
    node* nodeToDelete = stack;
    stack = stack->next;
    delete nodeToDelete;
    return key;
}

bool isOperator (char *token) {
    if (strcmp(token, "+") == 0) {
        return true;
    }
    else if (strcmp(token, "-") == 0) {
        return true;
    }
    else if (strcmp(token, "*") == 0) {
        return true;
    }
    else if (strcmp(token, "/") == 0) {
        return true;
    }
    else {
        return false;
    }
}



const bool is_empty() {
    return !top;
}

int postfix(const char *infix) {
    char infix_ch[100]={NULL};
    char postfix_ch[100]={NULL};
    node* stack = NULL;

    strcpy(infix_ch,"(");
    strcat(infix_ch, infix);
    strcat(infix_ch,")");

    char symbol[5]={NULL};
    char temp[5]={NULL};

    for(int i=0; i<strlen(infix_ch); i++) {
        symbol[0]=infix_ch[i];

        if(symbol[0]=='(')
            push(symbol[0]);

        else if(symbol[0]==')') {
            symbol[0]=pop( );
            while(symbol[0]!='(') {
                strcat(postfix_ch, symbol);
                symbol[0]=pop( );
            }
        }

         else if(symbol[0]=='^' || symbol[0]=='*' || symbol[0]=='/' || symbol[0]=='+' || symbol[0]=='-') {
            if(symbol[0]=='*' || symbol[0]=='/') {
                temp[0]=pop( );
                while(temp[0]=='^' || temp[0]=='*' || temp[0]=='/') {
                   strcat(postfix_ch, temp);
                   temp[0]=pop( );
                }
                push(temp[0]);
            }

            else if(symbol[0]=='+' || symbol[0]=='-') {
                temp[0]=pop( );
                while(temp[0]!='(') {
                    strcat(postfix_ch, temp);
                    temp[0]=pop( );
                }
                push(temp[0]);
            }
            push(symbol[0]);
        }

            else
                strcat(postfix_ch, symbol);
    }

       cout << "Postfix: " << postfix_ch;

       char postfix[80];
        cout << "\nEnter postfix expression (include spaces between each operand and/or operator): ";
       cin.getline(postfix, 80);
       char *tokens = strtok(postfix, " ");
       while (tokens != NULL) {
        if (isOperator (tokens)) {
            int operand2 = pop_for_output(stack);
            int operand1 = pop_for_output(stack);
            int result;

            if (strcmp(tokens, "+") == 0) {
                result = operand1 + operand2;
            }
            else if (strcmp(tokens, "-") == 0) {
                result = operand1 - operand2;
            }
            else if (strcmp(tokens, "*") == 0) {
                result = operand1 * operand2;
            }
            else if (strcmp(tokens, "/") == 0) {
                result = operand1 / operand2;
            }

            push_for_output (stack, result);
        }
        else {
            push_for_output (stack, atoi (tokens));
        }
        tokens = strtok(NULL, " ");
    }
    cout << pop_for_output(stack);
    system("pause");
    return 0;
}


 int main( ) {
    char infix_values[100]={NULL};
    cout << "Enter the infix equation: ";
    cin >> infix_values;
    postfix(infix_values);
}

我是新手,我真的需要各位专家的帮助。如果您帮助我更正我的程序,我将不胜感激。非常感谢您,祝您有愉快的一天!

【问题讨论】:

  • 你知道如何使用调试器吗?如果这样做,请使用它将问题缩小到一小段代码。当你这样做时,你可能会意识到你知道如何自己解决它。如果您不这样做,那么您可以只发布该代码并告诉您的发现,以便您可以帮助其他人帮助您。不要指望人们抓取你的代码,编译它,测试它,调试它。如果您不知道如何使用调试器,请先解决它!调试器是程序员必不可少的工具。
  • 哦,无论如何,你似乎主要学习 C,而不是 C++,所以我会给你一个链接到我们的list of good C++ books

标签: c++ linked-list infix-notation stack postfix-notation


【解决方案1】:

一个可能的问题是pop_for_output() 函数永远不会像在pop() 中那样检查空/NULL 堆栈。如果输入了无效的后缀表达式,或者您的解析不正确,您很容易陷入引用 NULL 指针的情况,这可以很好地解释崩溃。

【讨论】:

  • 谢谢!我现在放置 if (!top) { cout
  • 我假设您的意思是if (!stack) {...,因为您在 pop/push_for_output() 函数中使用了不同的堆栈对象。我会尝试输入一个简单的后缀表达式 (1 2 +) 并在调试器中逐步/跟踪代码,或者添加日志输出,以查看错误在哪里。
  • 再次感谢,但它仍然显示错误的输出——无论是堆栈还是顶部。不幸的是,我不知道如何使用(而且我没有)调试器,这就是我觉得这很难的原因。我是 C++ 新手。 :-)
  • 您可以在不同的地方添加一堆cout &lt;&lt; "..." 语句,而不是调试器,输出它的位置和堆栈的大小/内容。从简单的输入表达式开始,直到找到一个不起作用的表达式,然后查看输出,看看解析器在哪里没有按照您的想法执行。
猜你喜欢
  • 2013-02-26
  • 2012-06-26
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 2013-07-12
  • 2013-09-23
  • 2015-09-12
相关资源
最近更新 更多