用栈解决表达式求值问题。(提示,请采用链式存储结构)
一、问题描述
从键盘输入任意中缀表达式字符串,读字符串,利用栈结构实现表达式求值。
二、输入与输出
输入:从键盘中缀表达式如:32+5×(6-4)
输出:计算结果
42
问题描述:从键盘输入任意中缀表达式字符串,读字符串,利用栈结构实现表达式求值。
输入要求:1行中缀表达式(从键盘输入中缀表达式,如: 32+5×(6-4)# ),以#作为结束符
输出要求:1行结果(输出计算结果,如:42 )
示例如下:
解决思路:要建立两个栈,一个Opnd,一个栈存储运算符Oprt,当要入栈的运算符的优先级小于运算符栈顶元素的优先级,就将运算符栈顶运算符弹栈,并且弹出运算数栈Opnd的最顶的两个数,进行运算,将运算结果压入运算数栈Opnd中,继续此操作,直到运算符栈顶元素为“#”,结束此操作,然后弹出运算数栈Opnd栈顶元素作为运算结果。
代码:
#include<stdio.h>
#include<stdlib.h>
//定义数据栈结点
typedef struct StackNode1 {
int data;
struct StackNode1* next;
}StackNode1;
//定义栈
typedef struct LinkStack1 {
StackNode1* top;
int size;
}LinkStack1;
//OPND栈的初始化
LinkStack1* InitOPND() {
LinkStack1* L1 = (LinkStack1*)malloc(sizeof(LinkStack1));
L1->top = NULL;
L1->size = 0;
return L1;
}
//opnd入栈
void Push1(LinkStack1* L1, int e) {
StackNode1* p = (StackNode1*)malloc(sizeof(StackNode1));
p->data = e;
p->next = L1->top;
L1->top = p;
L1->size++;
printf("%d入Opnd栈成功\n", e);
}
//opnd出栈
void Pop1(LinkStack1* L1, int* e) {
if (L1->size == 0)
return;
*e = L1->top->data;
StackNode1* p = L1->top;
L1->top = L1->top->next;
free(p);
printf("%d出Opnd栈成功\n", *e);
}
//opnd取栈顶
int GetTop1(LinkStack1* L1) {
if (L1->size != 0)
return L1->top->data;
}
//定义运算符结点
typedef struct StackNode2 {
char data;
struct StackNode2* next;
}StackNode2;
//定义运算符栈
typedef struct LinkStack2 {
StackNode2* top;
int size;
}LinkStack2;
//optr初始化
LinkStack2* InitOPTR() {
LinkStack2* L2 = (LinkStack2*)malloc(sizeof(LinkStack2));
L2->top = NULL;
L2->size = 0;
return L2;
}
//optr入栈
void Push2(LinkStack2* L2, char ch) {
StackNode2* p = (StackNode2*)malloc(sizeof(StackNode2));
p->data = ch;
p->next = L2->top;
L2->top = p;
L2->size++;
printf("%c入Optr栈成功\n", ch);
}
//optr出栈
void Pop2(LinkStack2* L2, char* ch) {
if (L2->size == 0)
return;
*ch = L2->top->data;
StackNode2* p = L2->top;
L2->top = L2->top->next;
free(p);
printf("%c出Optr栈成功\n", *ch);
}
//optr取栈顶
char GetTop2(LinkStack2* L2) {
if (L2->size != 0) {
return L2->top->data;
}
}
//判断是否为运算符
int judge(char ch) {
if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
return 1;
return 0;
}
//比较运算符的优先级
char Precede(char ch1, char ch2) {
switch (ch1) {
case '+': {
switch (ch2) {
case '+': return '>';
case '-': return '>';
case '*': return '<';
case '/': return '<';
case '(': return '<';
case ')': return '>';
case '#': return '>';
}
}
case '-': {
switch (ch2) {
case '+': return '>';
case '-': return '>';
case '*': return '<';
case '/': return '<';
case '(': return '<';
case ')': return '>';
case '#': return '>';
}
}
case '*': {
switch (ch2) {
case '+': return '>';
case '-': return '>';
case '*': return '>';
case '/': return '>';
case '(': return '<';
case ')': return '>';
case '#': return '>';
}
}
case '/': {
switch (ch2) {
case '+': return '>';
case '-': return '>';
case '*': return '>';
case '/': return '>';
case '(': return '<';
case ')': return '>';
case '#': return '>';
}
}
case '(': {
switch (ch2) {
case '+': return '<';
case '-': return '<';
case '*': return '<';
case '/': return '<';
case '(': return '<';
case ')': return '=';
case '#': break;
}
}
case ')': {
switch (ch2) {
case '+': return '>';
case '-': return '>';
case '*': return '>';
case '/': return '>';
case '(': break;
case ')': return '>';
case '#': return '>';
}
}
case '#': {
switch (ch2) {
case '+': return '<';
case '-': return '<';
case '*': return '<';
case '/': return '<';
case '(': return '<';
case ')': break;
case '#': return '=';
}
}
}
}
//计算弹出的两个数的运算结果
int Operate(int a, char theta, int b) {
switch (theta) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return (a * b);
case '/':return a / b;
}
}
//定义运算器函数
int EvaluateExpression(LinkStack1* L1, LinkStack2* L2, char arr[]) {
Push2(L2, '#');
char* p = arr;
char theta, temp, out;
int sum;
// *p!= '#' || GetTop2(L2) != '#'
while (*p != '#' || GetTop2(L2) != '#') {
if (*p >= '0' && *p <= '9') {
sum = *p - '0';
char* q = p;
q++;
while (q != '\0') {
if (*q >= '0' && *q <= '9') {
sum = sum * 10 + *q - '0';
q++;
p++;
}
else
break;
}
Push1(L1, sum);
p++;
}
else {
printf("栈顶运算符为:%c\n", GetTop2(L2));
//有问题
switch (Precede(GetTop2(L2), *p)) {
case '<':
Push2(L2, *p++);
break;
case '>':
int a, b;
Pop2(L2, &theta);
Pop1(L1, &b);
Pop1(L1, &a);
Push1(L1, Operate(a, theta, b));
// p++;
break;
case '=':
char x;
Pop2(L2, &x);
p++;
break;
}
}
}
return GetTop1(L1);
}
int main() {
LinkStack1* L1;
LinkStack2* L2;
L1 = InitOPND();
L2 = InitOPTR();
printf("请输入表达式:\n");
char arr[20];
scanf("%s", arr);
printf("计算结果为:%d\n", EvaluateExpression(L1, L2, arr));
printf("计算结束!!\n");
}
调试:
“成长是一笔交易,我们都是用朴素的童真与未经人事的洁白交换长大的勇气。”