逆波兰表达式:
逆波兰表达式又叫做后缀表达式。逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。
Sample: a+b ---> a,b,+ a+(b-c)*d ---> a,b,c,-,d,*,+ a+d*(b-c)--->a,d,b,c,-,*,+
转换思路:
在表达式中的转换规则
操作数 :进栈
操作符 :(1)进栈:空栈
优先级高
栈顶是‘( ’同时表达式不是‘ )’
(2)出栈并计算:
表达式符号的优先级不高于栈顶符号
表达式为‘ )’同时栈顶不为‘( ’
表达式为‘\0’(即表达式结束)同时栈不为空
(3)出栈但不计算:表达式为‘ )’同时栈顶为‘( ’
运算符计算规则
如果读入的是数字,直接进栈;
如果是符号,必然是+-*/中的一个,直需要弹出栈顶的两个数,运算,然后再把结果进栈。直至扫描完整个后缀表达式,栈里就是最终结果。
附源码:(利用链式栈完成)
头文件:
#ifndef _LINKSTACK_H #define _LINKSTACK_H #define FAILURE 100001 #define SUCCESS 100002 #define TRUE 100003 #define FALSE 100004 typedef int Elemtype; struct node //节点信息 { Elemtype data; //数据域 struct node *next; //指针域 }; typedef struct node Node; struct stack //栈的信息 { Node *top; //头指针 int count; //节点个数 }; typedef struct stack Stack; int Stack_Init(Stack **s); int Stack_Empty(Stack *s); int Stack_Push(Stack **s, Elemtype e); int Stack_Gettop(Stack *s); int Stack_Pop(Stack **s); #endif
自定义函数:
#include "Linkstack.h" #include <stdio.h> #include <stdlib.h> int Stack_Init(Stack **s) { if(NULL == s) { return FAILURE; } (*s) = (Stack *) malloc (sizeof(Stack) * 1); if(NULL == (*s)) { return FAILURE; } (*s)->top = NULL; (*s)->count = 0; return SUCCESS; } int Stack_Empty(Stack *s) { if(NULL == s) { return FAILURE; } return (s->top == NULL) ? TRUE : FALSE; } int Stack_Push(Stack **s, Elemtype e) { if(NULL == s || NULL == (*s)) { return FAILURE; } Node *p = (Node *) malloc (sizeof(Node) * 1); p->data = e; p->next = (*s)->top; (*s)->top = p; (*s)->count++; return SUCCESS; } int Stack_Gettop(Stack *s) { if(NULL == s) { return FAILURE; } if(s->top == NULL) { return FAILURE; } return s->top->data; } int Stack_Pop(Stack **s) { if(NULL == s || NULL == (*s)) { return FAILURE; } Node *p = (*s)->top; Elemtype e = p->data; (*s)->top = p->next; free(p); (*s)->count--; return e; }
main主函数:
#include <stdio.h> #include "Linkstack.h" int Priority(char ch) { switch(ch) //优先级定义,“()”优先级最高,其次是“* /”,最后是“+ -” { case '(' : return 3; case '*' : case '/' : return 2; case '+' : case '-' : return 1; default : return 0; } } int main() { Stack *s_opt, *s_num; //定义两个链式栈,一个用来存放操作数,一个用来存放操作符 char opt[1024] = {0}; //存放表达式 int i = 0, tmp = 0, num1 = 0, num2 = 0; if(Stack_Init(&s_opt) != SUCCESS || Stack_Init(&s_num) != SUCCESS) 表达式没结束 或者 操作符栈不为空 { printf("Init Failure!\n"); } printf("Please input : \n"); scanf("%s", opt); while(opt[i] != '\0' || Stack_Empty(s_opt) != TRUE) { if(opt[i] >= '0' && opt[i] <= '9') //操作数 { tmp = tmp * 10 + opt[i] - '0'; i++; if(opt[i] > '9' || opt[i] < '0') //操作符 { Stack_Push(&s_num, tmp); tmp = 0; } } else { if(opt[i] == ')' && Stack_Gettop(s_opt) == '(') //出栈不计算 { Stack_Pop(&s_opt); i++; continue; } if(Stack_Empty(s_opt) == TRUE || (Priority(opt[i]) > Priority(Stack_Gettop(s_opt))) || (Stack_Gettop(s_opt) == '(' && opt[i] != ')')) //进栈 { Stack_Push(&s_opt, opt[i]); i++; continue; } if((opt[i] == '\0' && Stack_Empty(s_opt) != TRUE) || (opt[i] == ')' && Stack_Gettop(s_opt) != '(') || (Priority(opt[i]) <= Priority(Stack_Gettop(s_opt)))) //出栈计算 { switch (Stack_Pop(&s_opt)) { case '+' : num1 = Stack_Pop(&s_num); num2 = Stack_Pop(&s_num); Stack_Push(&s_num, (num1 + num2)); break; case '-' : num1 = Stack_Pop(&s_num); num2 = Stack_Pop(&s_num); Stack_Push(&s_num, (num2 - num1)); break; case '*' : num1 = Stack_Pop(&s_num); num2 = Stack_Pop(&s_num); Stack_Push(&s_num, (num1 * num2)); break; case '/' : num1 = Stack_Pop(&s_num); num2 = Stack_Pop(&s_num); Stack_Push(&s_num, (num2 / num1)); break; } } } } printf("运行结果为%d\n",Stack_Gettop(s_num)); return 0; }
示例:
代码如下: Input the Arithmetic type : 5+3*(1+2)-10/2+1 计算结果为: 5+3*(1+2)-10/2+1 = 10 !