利用栈将中缀表达式转换为后缀表达式并进行计算

[问题描述]
中缀表达式是最普通的一种书写表达式的方式,而后缀表达式不需要用括号来表示,计算机可简化对后缀表达式的计算过程,而该过程又是栈的一个典型应用。
[实验目的]
(1) 深入理解栈的特性。
(2) 掌握栈结构的构造方法。
[实验内容及要求]
(1) 中缀表达式中只包含+、-、×、/ 运算及( 和 )。
(2) 可以输入任意中缀表达式,数据为一位整数。
(3) 显示中缀表达式及转换后的后缀表达式(为清楚起见,要求每输出一个数据用逗
号隔开)。
(4) 对转换后的后缀表达式进行计算。
[测试数据]
(1) 6+3*(9-7)-8/2
转换后的后缀表达式为:6397-*+82/-
计算结果为:8
(2) (8-2)/(3-1)*(9-6)
转换后的后缀表达式为:82-31-/96-*
计算结果为:9

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 512

int top = -1;
int stack[512];

void Push(int e){
    if (top >= MAXSIZE){
        puts("栈已满");
        exit(1);
    }
    stack[++top] = e;

}
int isEmpty(){
    return top==-1?1:0;
}
int Pop(){
    if (top == -1){
        puts("这是一个空栈。");
        exit(1);
    }
    return stack[top--];
}

int getTop(){
    if (top < MAXSIZE)
        return stack[top];
    exit(1);
}

int judgePriority(char op1, char op2){
    // 1 先出栈, 再进栈
    // 0 直接进栈
    if (op1=='(' || op2 == '(')
        return 0;
    if ((op1=='-'||op1=='+')&& (op2 =='*'||op2 =='/'))
        return 0;
    return 1;
}
void infix2postfix(char *tmp, char *str){
    char *p = tmp;
    int i, j, k;
    char op1, op2;
    j = 0;
    for (i=0; p[i]; i++){
        // 数字
        if (p[i] >= '0' && p[i] <= '9')
            str[j++] = p[i];
        // 字符
        else{
            op1 = getTop();
            op2 = p[i];
            if (isEmpty())
                Push(op2);
            // 非空
            else{
                if (op2 == ')'){
                    while (getTop() != '(')
                        str[j++] = Pop();
                    Pop();
                    continue;
                }
                switch(judgePriority(op1, op2)){
                case  1: str[j++] = Pop(); 
                    for (k=0; k<=top; k++){
                        if (!judgePriority(op1, op2)) break;
                        str[j++] = Pop();
                    }
                    Push(op2);
                    break;
                case  0:  Push(op2); break;
                }
            }
        }
    }

    while (!isEmpty())
        str[j++] = Pop();
    str[j] = 0;
}

int calc(char *buf){
    int i, k, j;
    for (i=0; buf[i]; i++){
        switch(buf[i]){
        case '+':
            k = Pop() + Pop();
            Push(k);
            break;
        case '-':
            j = Pop();
            k = Pop() - j;
            Push(k);
            break;
        case '*':
            k = Pop() * Pop();
            Push(k);
            break;
        case '/':
            j = Pop();
            k = Pop()/j;
            Push(k);
            break;
        default:
            Push(buf[i]-48);
        }
    }
    return Pop();

}
int main(){
    char tmp[512]="9-2*2+(9-8)", str[512];
    puts("输入运算表达式:");
    gets(tmp);
    infix2postfix(tmp,str);
    puts(str);
    printf("%s = %d\n", tmp, calc(str));
}

这里写图片描述

转载于:https://www.cnblogs.com/laohaozi/p/8266616.html

以下是利用中缀表达式转换后缀表达式进行运算的C语言代码: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> typedef struct stack_node { char data; struct stack_node *next; } stack_node; typedef struct { stack_node *top; } stack; stack *create_stack() { stack *s = (stack *)malloc(sizeof(stack)); s->top = NULL; return s; } void push(stack *s, char c) { stack_node *node = (stack_node *)malloc(sizeof(stack_node)); node->data = c; node->next = s->top; s->top = node; } char pop(stack *s) { if (s->top == NULL) { printf("Error: stack is empty\n"); exit(1); } char c = s->top->data; stack_node *temp = s->top; s->top = s->top->next; free(temp); return c; } char peek(stack *s) { if (s->top == NULL) { printf("Error: stack is empty\n"); exit(1); } return s->top->data; } int is_empty(stack *s) { return (s->top == NULL); } int is_operator(char c) { return (c == &#39;+&#39; || c == &#39;-&#39; || c == &#39;*&#39; || c == &#39;/&#39;); } int precedence(char c) { switch (c) { case &#39;+&#39;: case &#39;-&#39;: return 1; case &#39;*&#39;: case &#39;/&#39;: return 2; default: return 0; } } char *infix_to_postfix(char *infix) { stack *s = create_stack(); char *postfix = (char *)malloc(sizeof(char) * (strlen(infix) + 1)); int i, j; for (i = 0, j = 0; infix[i] != &#39;\0&#39;; i++) { if (isdigit(infix[i])) { postfix[j++] = infix[i]; } else if (is_operator(infix[i])) { while (!is_empty(s) && is_operator(peek(s)) && precedence(peek(s)) >= precedence(infix[i])) { postfix[j++] = pop(s); } push(s, infix[i]); } else if (infix[i] == &#39;(&#39;) { push(s, infix[i]); } else if (infix[i] == &#39;)&#39;) { while (!is_empty(s) && peek(s) != &#39;(&#39;) { postfix[j++] = pop(s); } if (is_empty(s)) { printf("Error: mismatched parentheses\n"); exit(1); } pop(s); } else { printf("Error: invalid character\n"); exit(1); } } while (!is_empty(s)) { if (peek(s) == &#39;(&#39;) { printf("Error: mismatched parentheses\n"); exit(1); } postfix[j++] = pop(s); } postfix[j] = &#39;\0&#39;; return postfix; } int evaluate_postfix(char *postfix) { stack *s = create_stack(); int i, operand1, operand2, result; for (i = 0; postfix[i] != &#39;\0&#39;; i++) { if (isdigit(postfix[i])) { push(s, postfix[i] - &#39;0&#39;); } else if (is_operator(postfix[i])) { operand2 = pop(s); operand1 = pop(s); switch (postfix[i]) { case &#39;+&#39;: result = operand1 + operand2; break; case &#39;-&#39;: result = operand1 - operand2; break; case &#39;*&#39;: result = operand1 * operand2; break; case &#39;/&#39;: if (operand2 == 0) { printf("Error: division by zero\n"); exit(1); } result = operand1 / operand2; break; } push(s, result); } else { printf("Error: invalid character\n"); exit(1); } } result = pop(s); if (!is_empty(s)) { printf("Error: invalid expression\n"); exit(1); } return result; } int main() { char infix[100], *postfix; int result; printf("Enter an infix expression: "); scanf("%s", infix); postfix = infix_to_postfix(infix); printf("Postfix expression: %s\n", postfix); result = evaluate_postfix(postfix); printf("Result: %d\n", result); free(postfix); return 0; } ``` 该程序中,`stack_node`结构体表示中的节点,包含一个字符类型的数据`data`和一个指向下一个节点的指针`next`。`stack`结构体表示,包含一个指向顶节点的指针`top`。`create_stack`函数用于创建一个空,`push`函数用于将一个字符压入中,`pop`函数用于弹出顶字符,`peek`函数用于获取顶字符而不弹出,`is_empty`函数用于判断是否为空。 `is_operator`函数用于判断一个字符是否为运算符,`precedence`函数用于获取运算符的优先级。`infix_to_postfix`函数用于将中缀表达式转换后缀表达式,采用经典的算法:从左到右遍历中缀表达式,如果是数字直接输出到后缀表达式中,如果是左括号入,如果是右括号则弹出中的元素直到遇到左括号,如果是运算符则弹出中优先级大于等于它的元素输出到后缀表达式中,然后将自己入。最后将中剩余的元素弹出输出到后缀表达式中。在转换过程中需要处理一些错误情况,如不合法的字符、不匹配的括号等。 `evaluate_postfix`函数用于计算后缀表达式的值,也是采用经典的算法:从左到右遍历后缀表达式,如果是数字则入,如果是运算符则弹出中的两个操作数进行运算,将结果入。最后中剩下的元素就是表达式的值。 在`main`函数中,首先读入中缀表达式,然后调用`infix_to_postfix`函数将其转换后缀表达式输出后缀表达式。接着调用`evaluate_postfix`函数计算后缀表达式的值,输出结果。最后释放动态分配的内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值