Op->top=Op->top+1;/*若栈不满,则将e进栈*/
Op->array[Op->top]=e;/*栈顶元素变为e*/
return1;}
else{/*若栈判断为满,则返回0*/
return0;}}
ElemTypeOppop(OpNode*Op){/*定义操作符栈出栈函数*/
ElemTypen;
if(-1==Op->top){/*判断栈顶是否为空,若栈顶为空,则返回1*/
return1;}
else{
n=Op->array[Op->top];/*若栈顶不为空,则将栈顶元素n出栈*/
(Op->top)--;/*有元素出栈,top自减*/
returnn;}}
intGetTop(OpNodeOp,ElemType*e){/*定义取出栈顶元素的函数*/
if(0==Op.top){/*若栈顶元素为空,则返回0*/
*e=Op.array[Op.top];/*指针e指向栈顶元素*/
return0;}
else{/*若栈顶元素不为空,则返回1*/
*e=Op.array[Op.top];/*指针e指向栈顶元素*/
return1;}}
intSLevel(intmode,charoper){/*定义比较操作符优先级的函数*/
/*返回操作符oper代表优先级的整数值,mode为1,表示oper是栈顶操作符,否则是当前操作符*/
inttmp;/*定义临时变量*/
switch(oper){
case'#':
tmp=0;break;/*定义#优先级为0*/
case'(':
tmp=(mode?
1:
6);break;/*若(是栈顶操作符,则优先级为1,否则优先级为6*/
case'+':
case'-':
tmp=(mode?
3:
2);break;/*若+或-是栈顶操作符,则优先级为3,否则优先级为2*/
case'*':
case'/':
case'%':
tmp=(mode?
5:
4);break;/*若*、/或%是栈顶操作符,则优先级为5,否则优先级为4*/
case')':
tmp=(mode?
7:
1);break;/*若)是栈顶操作符,则优先级为7,否则优先级为1*/
}
returntmp;}/*返回所得tmp的值*/
charCLevel(charw,charch){/*判定操作符栈的栈顶操作符w与当前操作符ch之间的优先级关系*/
intgrade;/*取得栈顶操作符与当前操作符的优先级*/
grade=SLevel(1,w)-SLevel(0,ch);/*计算取得操作符与当前操作符的差值*/
if(grade>0)/*差值大于0,返回>*/
return'>';
else{
if(grade==0)/*说明取得操作符和当前操作符优先级相等*/
return'=';
else/*否则,取得操作符优先级小于当前操作符*
return'<';}}
voidchange(charE[],charA[]){/*中缀变后缀的实现函数*/
/*E为原前缀式,A为要得到的后缀式*/
OpNodeOp;/*声明一个操作符栈Op*/
inti=0;/*i作为扫描数组E的指针*/
intj=0;/*j用来指示数组A中待写入字符的位置*/
charch=E[i];/*E中第一个字符送给ch*/
charw='\0';
OpInit(&Op);/*初始化操作符栈Op*/
Oppush(&Op,'#');/*先把#压入栈内*/
while(ch!
='#'){/*当ch取得的元素不是#时执行以下命令*/
if(ch>='0'&&ch<='9'||ch=='.'){/*若取得的元素为0到9或者是小数点*/
while(ch>='0'&&ch<='9'||ch=='.'){
A[j]=ch;/*将获得的元素赋予A数组*/
j++;/*A写入位置后移*/
i++;/*E向后扫描*/
ch=E[i];}/*将数组E的下一个元素赋值给ch*/
A[j]='';
j++;}/*给A中的每个数后加一个空格*/
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'
||ch=='%'||ch=='('||ch==')'||ch=='#'){/*若取得的元素为操作符*/
GetTop(Op,&w);/*取Op的栈顶元素*/
while(CLevel(w,ch)=='>'){/*栈顶操作符w比取得的操作符ch的优先级大*/
A[j]=w;/*将w赋予数组A*/
j=j+1;
Oppop(&Op);/*将栈顶操作符w出栈*/
GetTop(Op,&w);}/*取得的操作符入栈*/
if(CLevel(w,ch)=='<')/*若栈顶操作符w比取得的操作符ch的优先级小*/
Oppush(&Op,ch);/*取得的操作符直接入栈*/
else{
if(CLevel(w,ch)=='='&&w!
='#'){/*若栈顶操作符w与取得的操作符ch的优先级相等*/
Oppop(&Op);/*将栈顶操作符出栈*/
GetTop(Op,&w);}}}/*观察栈顶操作符*/
if(E[i]!
='#')/*若取得的字符不是#,i加1*/
i++;
ch=E[i];}/*将从E数组取出的元素赋予ch*/
while(w!
='#'){/*取得的操作符不是#*/
A[j]=w;/*将操作符赋予A数组*/
j++;
Oppop(&Op);/*Op栈顶元素出栈*/
GetTop(Op,&w);}
A[j]='#';
A[++j]='\0';}
doubleCalc(chararr[]){/*计算后缀表达式的值*/
OdNodeOd;/*声明一个数值栈Od*/
inti=0;/*定义临时变量i*/
charch;
doublex=0,d=1.0;
OdInit(&Od);/*初始化数值栈*/
ch=arr[i];/*将受到的数组的元素赋值给ch*/
while(ch!
='#'){
switch(ch){/*读取字符串中的数值部分*/
case'0':
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
case'.':
while(ch!
=''){/*取得的字符不为空*/
if('0'<=ch&&ch<='9'){
while('0'<=ch&&ch<='9'){/*每读到一个整数部分就*10*/
x=x*10+(ch-'0');
i=i+1;
ch=arr[i];}}
else{if(ch=='.'){
ch=arr[++i];
while('0'<=ch&&ch<='9'){/*每独到一个小数部分就/10*/
d=d*10;
x=x+(ch-'0')/d;
ch=arr[++i];}}}}break;/*读取数组下一个元素*/
case'+':
/*若取得的字符为+,从数值栈取两个元素进行+运算*/
x=Odpop(&Od)+Odpop(&Od);break;
case'-':
/*若取得的字符为-,从数值栈取两个元素进行-运算*/
x=Odpop(&Od);
x=Odpop(&Od)-x;break;
case'*':
/*若取得的字符为*,从数值栈取两个元素进行*运算*/
x=Odpop(&Od)*Odpop(&Od);break;
case'/':
/*若取得的字符为/,从数值栈取两个元素进行/运算*/
x=Odpop(&Od);
x=Odpop(&Od)/x;break;
case'%':
/*若取得的字符为%,从数值栈取两个元素进行%运算*/
x=Odpop(&Od);
x=(double)((int)Odpop(&Od)%(int)x);break;}
Odpush(&Od,x);/*将计算结果x入栈*/
x=0;/*x归零*/
i=i+1;
ch=arr[i];/*继续进行*/
d=1.0;}/*d归零*/
returnOdpop(&Od);}/*返回数值栈顶元素,即结果值*/
voidmain(){/*主函数*/
charE[100];/*声明一个长度为100的数组E*/
charA[100];/*声明一个长度为100的数组A*/
printf("Pleaseinputtheinfixexpresswitha'#'inttheend:
");/*输出提示信息*/
gets(E);/*获取E数组中的表达式*/
change(E,A);/*调用中缀式转后缀式函数*/
printf("Thesurffixexpressis:
%s\n",A);/*输出后缀式*/
printf("Theresultis:
%f\n",Calc(A));/*调用计算后缀式的函数,并将结果输出*/
getchar();}
下面给出的是用中缀表达式直接进行入栈计算算法实现的程序的源代码:
#include
#include
#include
typedefstruct{/*声明操作符结构体*/
charop;/*声明操作符类型*/
charlevel;/*声明操作符优先级*/
}opNode;
typedefunion{
opNodeopNode;/*声明操作符*/
doublevalue;/*声明value数值为double型*/
}Node;
typedefstruct{/*声明栈的结构体*/
charleixing;/*声明一个字符型sort*/
Node*a[100];/*指定数组大小为100*/
inttop;/*声明栈顶*/
}Stack;
Stack*init_sta(){/*初始化栈*/
inti;
Stack*s=(Stack*)malloc(sizeof(Stack));/*分配一个类型为Stack的
结点变量的空间,空间大小为sizeof(Stack),并将首地址放入指针变量s中*/
s->top=0;
for(i=0;i<100;i++)/*遍历栈,全为空则栈空*/
s->a[i]=NULL;
returns;}
char*substr(char*s,intn1,intn2){/*截取子串函数*/
char*ss=(char*)malloc(sizeof(char)*(n2-n1+2));/*分配空间,大小为
n2-n1+2,并将首地址放入指针变量ss中*/
inti,j=0;
for(i=n1;iss[j++]=s[i];}
ss[j]='\0';/*字符串后面加上'0'*/
returnss;}
intempty(Stack*ss){/*判断栈空函数*/
returnss->top;}/*返回栈顶元素*/
Node*Top(Stack*ss){/*观察栈顶函数*/
if(ss->top<=0){/*若栈顶为空,则返回0*/
return0;}
else{/*若栈顶不为空,则返回栈顶元素*/
returnss->a[ss->top-1];}}
Node*Pop(Stack*ss){/*出栈函数*/
if(ss->top<=0){/*栈顶为空,返回0*/
return0;}
else{/*否则,栈顶元素出栈*/
ss->top--;
returnss->a[ss->top];}}
voidPush(Stack*p,Node*n){/*进栈函数*/
Node*temp=(Node*)malloc(sizeof(Node));/*分配空间,空间大小为
sizeof(Node),并将首地址放入指针变量temp中*/
if(p->top>=100){/*判断栈是否已满*/
printf("Error!
TheStackisfull!
\n");/*输出提示信息*/
free(temp);}
else{
if(p->leixing==1){/*sort为1,指向的为操作符栈,表明temp为操作符*/
temp->opNode.level=n->opNode.level;
temp->opNode.op=n->opNode.op;}
else/*sort为2指向的是数值栈,表明temp为数值*/
temp->value=n->value;
p->a[p->top]=temp;
p->top=p->top+1;}}
doublecalc(charop,doublem,doublen){/*每出栈一个操作符,就进行一次运算*/
switch(op){
case'+':
returnn+m;
case'-':
returnn-m;
case'*':
returnn*m;
case'/':
returnn/m;
case'%':
return(int)n%(int)m;}/*计算结束后,返回计算结果*/
return0;}
voidmath(char*exp){/*处理函数*/
Node*top;/*声明栈顶*/
Node*temp=(Node*)malloc(sizeof(Node));/*分配空间,并将首地址放入指针变量temp中*/
Node*tempn=(Node*)malloc(sizeof(Node));/*分配空间,并将首地址放入指针变量tempn中*/
Node*tempm;/*声明一个tempm结点指针*/
charc;
char*temps="";
unsignedintindex=0,tempindex;/*声明一个索引和一个临时索引*/
doublea,b;
Stack*s1=init_sta();/*初始化栈s1*/
Stack*s2=init_sta();/*初始化栈s2*/
s1->leixing=2;/*s1的类型为2,栈为数值栈*/
s2->leixing=1;/*s2的类型为1,栈为操作符栈*/
while(indexc=exp[index];
if(c>='0'&&c<='9'||c=='.'){/*读取表达式中的各个数值*/
tempindex=index+1;
while(tempindex='0'&&exp[tempindex]<='9'||exp[tempindex]=='.')){
tempindex++;}/*当一个数没有读完,索引后移,直至整个数读完*/
if(tempindex==strlen(exp)-1){/*当临时索引到达表达式尾部时,直接截取*/
temps=substr(exp,index,index+1);}
else{
temps=substr(exp,index,tempindex);}
index=tempindex;/*索引指向临时索引所在位置*/
temp->value=atof(temps);/*将截取的子串转化为double类型*/
Push(s1,temp);}/*将转化后的数压入数值栈*/
if(c=='+'||c=='-'){/*字符为+或-时*/
tempn->opNode.op=c;
tempn->opNode.level=1;/*设置优先级为1*/
top=Top(s2);
while(empty(s2)>0&&tempn->opNode.level<=top->opNode.level){/*操作符栈不为空,
并且栈顶操作符优先级高于或者等于当前操作符*/
tempm=Pop(s2);/*操作符栈顶操作符出栈*/
a=Pop(s1)->value;/*数值栈顶出来两个数*/
b=Pop(s1)->value;
temp->value=calc(tempm->opNode.op,a,b);/*两个数进行运算*/
Push(s1,temp);/*运算结果压入数值栈*/
top=Top(s2);}
Push(s2,tempn);
index++;}
if(c=='*'||c=='/'||c=='%'){/*字符为*或/或%时*/
tempn->opNode.op=c;/*临时操作符指向c*/
tempn->opNode.level=2;