实验5 表达式求值 实验目的 1. 会定义顺序栈和链栈的结点类型。 2. 掌握栈的插入和删除结点在操作上的特点。 3. 熟悉对栈的一些基本操作和具体的函数定义。 实验内容 程序1 该程序的功能是实现顺序栈的定义和操作。该程序包括定义的栈结构类型以及对每一种栈操作的具体的函数定义和主函数。 /* 定义DataType为int类型 */ typedef int DataType; /* 栈的结点类型 */ #define MAXSIZE 1024 typedef struct {DataType data[MAXSIZE]; int top; }SeqStack; /* 初始化顺序栈 */ SeqStack SeqStackInit() /* 检查顺序栈是否为空 */ int SeqStackEmpty(SeqStack S) /* 把S置为空栈 */ void ClearStack(SeqStack S) /* 把元素x压入栈,使其成为新的栈顶元素 */ void SeqStackPush(SeqStack S,DataType x) /* 把栈顶元素弹出 */ DataType SeqStackPop(SeqStack S) /* 取栈顶元素 */ DataType SeqStackGetTop(SeqStack S) /*输出顺序栈中的元素*/ void SeqStackPrint(SeqStack S) 程序2 用顺序栈实现算术表达式求值。 将表达式看成字符串序列,输入语法正确、不含有变量的整数表达式(表达式中的数字限为单位数),利用算符的优先关系,把中序表达式转换为后序表达式后输出,然后求出该后序表达式的值。 例如:输入的表达式为2*(6-4)+8/4 转换后得到的后序表达式为264-*84/+ 设计要求:在程序中构造六个子程序分别为 int empty(SeqStack stack); /*检查栈是否为空*/ int operation(char op); /*判断是否为运算符*/ int priority(char op); /*判断运算符的优先权*/ SeqStack push(SeqStack stack,char value); /*入栈*/ SeqStack pop(SeqStack stack,char *value); /*出栈*/ double count(char *backorder); /*计算逆波兰表达式的值*/ 程序3 用链栈实现算术表达式求值。(与程序2的基本要求相同) 链栈结点的类型描述如下: typedef int DataType; typedef struct StackNode {DataType data; struct StackNode *next; }StackNode,*LinkedStack;
“运算符优先级表” - 参考博客:http://www.jb51.net/article/37289.htm
/* 程序1 该程序的功能是实现顺序栈的定义和操作。该程序包括定义的栈结构类型以及对每一种栈操作的具体的函数定义和主函数。 */ #include <stdio.h> #include <stdlib.h> /* 定义DataType为int类型 */ typedef int DataType; /* 栈的结点类型 */ #define MAXSIZE 1024 typedef struct{ DataType data[MAXSIZE]; int top; }SeqStack; /* 初始化顺序栈 */ SeqStack SeqStackInit() { SeqStack q; q.top = -1; return q; } /* 检查顺序栈是否为空 */ int SeqStackEmpty(SeqStack S) { if(S.top==-1) //栈空 return 1; else return 0; } /* 把S置为空栈 */ void ClearStack(SeqStack &S) { S.top = -1; } /* 把元素x压入栈,使其成为新的栈顶元素 */ void SeqStackPush(SeqStack &S,DataType x) { if(S.top==MAXSIZE-1) //已经满了 printf("入栈失败,栈已满! "); else { S.top++; S.data[S.top] = x; } } /* 把栈顶元素弹出 */ DataType SeqStackPop(SeqStack &S) { if(S.top==-1){ //栈已空 printf("出栈失败,栈已空! "); return 0; } else { DataType x = S.data[S.top--]; return x; } } /* 取栈顶元素 */ DataType SeqStackGetTop(SeqStack S) { return S.data[S.top]; } /*输出顺序栈中的元素*/ void SeqStackPrint(SeqStack S) { int top = S.top; while(top!=-1) printf("%d ",S.data[top--]); } int Menu() //显示菜单,返回命令 { int in; printf("[1] 检查顺序栈是否为空 "); printf("[2] 把S置为空栈 "); printf("[3] 把元素x压入栈,使其成为新的栈顶元素 "); printf("[4] 把栈顶元素弹出 "); printf("[5] 取栈顶元素 "); printf("[6] 输出顺序栈中的元素 "); printf("[0] 按其它键退出 "); scanf("%d",&in); return in; } void Reply(int in,SeqStack &S) //对命令的反应 { int x; switch(in){ case 1: if(SeqStackEmpty(S)) printf("栈为空! "); else printf("栈未空! "); break; case 2: ClearStack(S); //将S置为空栈 printf("已成功置为空栈! "); break; case 3: printf("请输入你要压栈的元素: "); scanf("%d",&x); SeqStackPush(S,x); break; case 4: SeqStackPop(S); break; case 5: if(SeqStackEmpty(S)) printf("栈当前为空,栈顶无元素! "); else printf("栈顶元素为:%d ",SeqStackGetTop(S)); break; case 6: if(SeqStackEmpty(S)) printf("栈当前为空! "); else{ printf("栈中元素为(从顶至下): "); SeqStackPrint(S); } break; default: exit(1); } system("pause"); system("cls"); } int main() { SeqStack S = SeqStackInit(); while(1){ int in = Menu(); Reply(in,S); } return 0; }
1 /* 程序2 用顺序栈实现算术表达式求值。 2 将表达式看成字符串序列,输入语法正确、不含有变量的整数表达式(表达式中的数字限为单位数) 3 利用算符的优先关系,把中序表达式转换为后序表达式后输出,然后求出该后序表达式的值。 4 例如:输入的表达式为2*(6-4)+8/4 5 转换后得到的后序表达式为264-*84/+ 6 设计要求:在程序中构造六个子程序分别为 7 */ 8 #include <stdio.h> 9 #include <stdlib.h> 10 /* 定义DataType为int类型 */ 11 typedef char DataType; 12 13 /* 栈的结点类型 */ 14 #define MAXSIZE 1024 15 typedef struct{ 16 char data[MAXSIZE]; 17 int top; 18 }SeqStack; 19 SeqStack op; //运算符栈和表达式栈 20 21 int Prior[6][6] = //Prior[lop][rop] 22 { // 运算符优先级表 23 // '+' '-' '*' '/' '(' ')' 24 /*'+'*/-1,-1,1,1,1,-1, 25 /*'-'*/-1,-1,1,1,1,-1, 26 /*'*'*/-1,-1,-1,-1,1,-1, 27 /*'/'*/-1,-1,-1,-1,1,-1, 28 /*'('*/1,1,1,1,1,0, 29 /*')'*/-1,-1,-1,-1,0,-1 30 }; 31 32 int empty(SeqStack stack) /*检查栈是否为空*/ 33 { 34 if(stack.top==-1) //栈空 35 return 1; 36 else 37 return 0; 38 } 39 int operation(char op) /*判断是否为运算符*/ 40 { 41 if('0'<=op && op<='9') //是单位数字,不是运算符 42 return 0; 43 else 44 return 1; 45 } 46 int priority(char rop) /*判断运算符的优先权*/ 47 { 48 char lop = op.data[op.top]; 49 int a,b; 50 switch(lop){ 51 case '+':a=0;break; 52 case '-':a=1;break; 53 case '*':a=2;break; 54 case '/':a=3;break; 55 case '(':a=4;break; 56 case ')':a=5;break; 57 default:break; 58 } 59 switch(rop){ 60 case '+':b=0;break; 61 case '-':b=1;break; 62 case '*':b=2;break; 63 case '/':b=3;break; 64 case '(':b=4;break; 65 case ')':b=5;break; 66 default:break; 67 } 68 return Prior[a][b]; 69 } 70 SeqStack push(SeqStack stack,char value) /*入栈*/ 71 { 72 if(stack.top==MAXSIZE-1) //已经满了 73 printf("入栈失败,栈已满! "); 74 else { 75 stack.top++; 76 stack.data[stack.top] = value; 77 } 78 return stack; 79 } 80 SeqStack pop(SeqStack stack,char *value) /*出栈*/ 81 { 82 if(stack.top==-1){ //栈已空 83 printf("出栈失败,栈已空! "); 84 return stack; 85 } 86 else { 87 *value = stack.data[stack.top--]; 88 return stack; 89 } 90 } 91 double count(char *backorder) /*计算逆波兰表达式的值*/ 92 { 93 struct { 94 double data[MAXSIZE]; 95 int top; 96 } ds; //数栈 97 ds.top = -1; 98 int i; 99 for(i=0;backorder[i];i++) 100 if(operation(backorder[i])){ //是运算符 101 double a,b; 102 b = ds.data[ds.top--]; //从数栈中依次取出两个数 103 a = ds.data[ds.top--]; 104 switch(backorder[i]){ //运算并入栈 105 case '+':ds.top++;ds.data[ds.top] = a+b;break; 106 case '-':ds.top++;ds.data[ds.top] = a-b;break; 107 case '*':ds.top++;ds.data[ds.top] = a*b;break; 108 case '/':ds.top++;ds.data[ds.top] = a/b;break; 109 default:break; 110 } 111 } 112 else{ //是数,直接入数栈 113 ds.top++; 114 ds.data[ds.top] = double(backorder[i] - '0'); 115 } 116 return ds.data[ds.top]; 117 } 118 void trans(char exp[],char backorder[]) //将中序表达式转换成后缀表达式,存储一字符串中 119 { 120 int index=0; 121 int len = 0; 122 while(exp[index]){ 123 if(operation(exp[index])){ //是运算符 124 if(empty(op)){ //如果运算符栈为空,直接入栈 125 op = push(op,exp[index++]); 126 } 127 else{ //运算符栈不为空,与将该运算符与栈顶运算符比较 128 char c; 129 switch(priority(exp[index])){ 130 case 1: //当前运算符比栈顶运算符优先级高 131 op = push(op,exp[index++]); 132 break; 133 case 0: //运算符优先级相等。只出现在栈顶为'('和当前为')'的情况 134 op = pop(op,&c); 135 index++; 136 break; 137 case -1: //当前运算符优先级低 138 op = pop(op,&c); //退栈 139 backorder[len++] = c; //将运算符放入字符串中 140 break; 141 default:break; 142 } 143 } 144 } 145 else{ //是数字。直接压栈 146 backorder[len++] = exp[index++]; //将数字放入字符串中 147 } 148 } 149 while(!empty(op)){ //如果运算符栈不为空,全部出栈 150 char c; 151 op = pop(op,&c); //退栈 152 backorder[len++] = c; //将运算符放入字符串中 153 } 154 backorder[len] = '