表达式求值算法----栈的应用

关于表达式求值这个算法:这个算法算是比较基本的算法了,但是应用面也特别广,在写之前查阅了很多资料看了很多前辈写的一些经验确实学到了很多,过程也比较曲折。一开始先是对几个运算符的优先级问题感到头疼。后来又进一步了解到了表达式的转换问题———中缀表达式转换为后缀表达式。因为后缀表达式在计算机计算的时候会比较方便,尽管中缀表达式比较适合人的思维。

下面是摘抄的一些方法:

首先创建栈并置空,然后依次检查中缀表达式每个字符,不同字符按不同情况处理: (1).若是操作数,就直接将存入字符串exp[]中。 (2).若是‘(’则将其压入栈中。 
(3).若是‘)’则依次弹栈并存入字符串exp[]中,直到遇到取出和它匹配的‘(’为止,‘(’出栈丢弃。 
(4).若是操作符,如果栈空或者该操作符的优先级大于栈顶操作符则将其放入到栈中。如果该操作符的优先级小于等于栈顶操作符则弹出栈中的操作符存入字符串exp[]中,直到该操作符的优先级大于栈顶操作符或栈空,然后将该操作符入栈。 
当读到了中缀式的末尾时,如果栈非空则将栈中所有元素依次弹出存入字符串exp[]中,最后见‘\0’存入exp[]中,则exp[]中存储的就是后缀表达式。 


下面是我写的源码:

#include<stdio.h>
#include<math.h>
#include<String.h>
#include<stdlib.h>


#define Max 100
struct stack{
char h[Max];
int top;
};


int initStack(stack* s){
if((s=(stack*)malloc(sizeof(stack)))==NULL)
 return 1;
 s->top=-1;
 return 0;
}


int stackFull(stack* s){
if(s->top==Max)
    return 1;    // 栈满  返回0    未满返回1 
    else  
     return 0;
}


int stackEmpty(stack*s){
if(s->top==-1)    // 栈空   返回0     未空返回1 
  return 1;
else
return 0;
}


void push(stack* s,char c){   
if(stackFull(s))
  printf("the Stack is full");
else 
 s->h[++(s->top)]==c;
 
}


void popStack(stack*s,char c){
if(stackEmpty(s))
  printf("the Stack is empty");
else
  c=s->h[s->top];
  --(s->top);
}


char getTop(stack*s,char c){
if(stackEmpty(s)){
   printf("the Stack is empty");
   return 0;}   
  else{
  c=s->top;
       return c;}
}


int setPriority(char e){
int i;
switch('e'){
case'+':
case'-': 
       i=1;break;
case'*':
   case'/': 
           i=2;break;
   case'(':
case')':
       i=3;break;
   defult:printf("enter data error!\n ");   
}
return i;
}


void transform(char h[],char num[]){   // 将中缀表达式转换成为后缀表达式 
int i=0,j=0;
char e,f;
stack *optr;
initStack(optr);
e=h[i]; 
while(e!='\0'){
if(e>'0'&&e<='9'){
num[j]=e;
++j;
}
else if(e=='+'||'-'||'*'||'/'||'('||')'){
if(stackEmpty(optr)||e=='(')  push(optr,e);
else if(e==')'){
do{
popStack(optr,f);
num[j++]=f;
}while(!getTop(optr,f)=='(');   //  采用do while而不是while是因为这样可以先运行循环体 
popStack(optr,f); 


else if(setPriority(e)>=setPriority(optr->h[optr->top])) {
                                                         push(optr,e);}
else if(setPriority(e)<=setPriority(optr->h[optr->top])) {
                                                         num[j++]=e;}   

                

++i;
e=h[i];
}
 

}


int main(){
char h[14]="9+(3-1)*3+4-2";
char num[Max];
transform(h,num);
printf("%s",num);
return 0;
}


因为主要是想熟悉栈的应用,所以就没有标准输入。

在写的过程中遇到了一些问题:

1、字符的运算 。因为在一开始考虑数据结构的时候确实遇到了这个问题,一个正常的表达式中是存在字符型和整型两种类型的。但是当我将它放入一个字符数组然后再单独取出运算的时候,发现字符也可以进行四则运算(以%d形式输出)

2、sizeof()。 在initStack()函数中sizeof(somestruct) 的时候发现一个很奇怪的问题,可能我现在还没有学到这一块知识。在网上搜索的时候才知道是关于 内存对齐 的内容。

3、对于运算符优先级的设置问题。这个问题也是奇葩,一开始我自己想的确实头疼,因为几个字符之间的大小对比因为不知道他们的大小也不好直接equal ,后来通过switch(i)设置大小才通过。

4、else if 。  如果else if 过多的话  不妨用switch试试

5、当时是stack的熟悉和运用了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值