无符号表达式求值
- 利用栈的特性进行表达式计算。
- 主要思路是做一个数字栈和一个符号栈,分别存放数字和运算符。
- 利用入栈的运算符和栈内运算符相比较优先级达到计算目的。
代码收获
- atoi字符串转数字功能在devc++上调试时结果正确,运行时结果错误。经研究发现,这个函数在转字符时候会在运行的情况里把转的字符末尾加0,而调试的时候不会。比如转字符‘5’,atoi就会转成50,从而影响最后结果。后发现atoi是转字符串,字符串是字符数组最后需要带尾零,可能是由于字符不是字符串导致的问题。
- 入栈运算符的优先级如果是同级,也需要进行栈内数字运算。
- 此代码只能进行个位数的无符号表达式求值,思考后发现,将输入的值做成队列,然后可以算得数字位数,从而进行多位数的表达式求值。
栈的归档
栈的存储结构(一)顺序栈
栈的存储结构(二)双端栈
栈的存储结构(三)链栈
栈的运用(一)无括号表达式求值
栈的运用(二)无括号表达式求值修正版
# include <stdio.h>
# include <stdlib.h>
#define MAXSIZE 100
typedef struct stack{
int top;
int ele[MAXSIZE];
}stacknum,*stacknump;
typedef struct stackop{
int top;
char ele[MAXSIZE];
}stackop,*stackopp;
//初始化
void InitialStack(stacknump* ST,stackopp* OP){
*ST=(stacknump)malloc(sizeof(stacknum));
*OP=(stackopp)malloc(sizeof(stackop));
(*ST)->top = -1;//栈顶指针为-1 说明是空栈,和顺序存储思想相似
(*OP)->top = -1;
}
char getops(stackopp OP){//获取操作栈顶元素并返回元素
return OP->ele[OP->top];
}
int getint(char *a){//字符转换数字
return *a-'0';
}
int compareop(char a,stackopp OP){//比较优先级 $ (+-) (*/) $是0 +-做1 乘除做2 如果第一个数减第二个数负数,则优先级比第二个数高,等于0表示相等,小于0表示优先级小
char b;
b = getops(OP);
int aa,bb;
switch(a){
case '$': {
aa=0;
break;
}
case '+':
case '-':{
aa=1;
break;
}
case '*':
case '/':{
aa=2;
break;
}
}
switch(b){
case '$': {
bb=0;
break;
}
case '+':
case '-':{
bb=1;
break;
}
case '*':
case '/':{
bb=2;
break;
}
}
if(aa-bb>0){//1代表要入栈的比栈顶优先级高,0代表相等,-1代表小于
return 1;
}else if(aa-bb==0){
return 0;
}else{
return -1;
}
}
int excuit(int num2,int num1,char ops){//运算
switch(ops){
case '+':{
return num2+num1;
}
case '-':{
return num2-num1;
}
case '*':{
return num2*num1;
}
case '/':{
return num2/num1;
}
}
}
//入栈
//看要进栈的优先级是否高于栈顶优先级
//比符号栈顶高进栈
//比符号栈顶低取出元素栈顶元素和元素栈顶下的元素
//取出符号栈顶的元素进行计算
//将结果进元素栈后继续比较将进栈符号的优先级,比栈顶符号高就进栈,低就继续走上述运算。
int CauculateStack(stacknump ST,stackopp OP){
printf("输入数字与运算符,$结束\n");
OP->top++;
OP->ele[OP->top]='$';//先将操作栈入$
int flag = 1;
while(flag){
char c;
c = getchar();
if(c!='$'){
switch(c){
case '+':
case '-':
case '*':
case '/':{
//取出前面一个数对比将要入栈的优先级
int flag2=1;
while(flag2){
int prime;
prime = compareop(c,OP);
if(prime>0){
OP->top++;//操作符入栈
OP->ele[OP->top]=c;
flag2=0;
}else{//取出数字栈的2个数并且取出操作符中的一个数进行运算 再将运算结果入数字栈
int num1,num2;
char ops;
num1 =ST->ele[ST->top];
ST->top--;
num2 = ST->ele[ST->top];
ST->top--;
ops = getops(OP);
OP->top--;
int res;
res = excuit(num2,num1,ops);
ST->top++;
ST->ele[ST->top]=res;
}
}
break;
}
default:{//数字直接入栈
int numb;
numb = getint(&c);
ST->top++;
ST->ele[ST->top]=numb;
break;
}
}
} else{
flag = 0;
//只要操作栈不为最初的那个$,就进行运算;
while(OP->top!=0){
//出数字栈2个然后出运算栈1个 结果入栈
int num3,num4;
char ops2;
num3 =ST->ele[ST->top];
ST->top--;
num4 = ST->ele[ST->top];
ST->top--;
ops2 = getops(OP);
OP->top--;
int res2;
res2= excuit(num4,num3,ops2);
ST->top++;
ST->ele[ST->top]=res2;
}
}
}getchar();
printf("结果为%d",ST->ele[0]);//打印结果为数字栈的第一个
return 0;
}
void main(){
stackopp OP;
stacknump ST;
InitialStack(&ST,&OP);
CauculateStack(ST,OP);
}
终端显示
输入数字与运算符,$结束
5*5-2+3*3+2-5*9$
结果为-11