栈的应用(表达式求值--中缀表达式)C实现

一、准备工作

  1.  对于使用栈来进行表达式求值,使用顺序栈即可
  2. 定义两个栈,一个操作数栈(int 数据类型),一个运算符栈(char 数据类型)。
  3. 两个栈都应该具备:初始化,入栈,出栈,取栈顶元素这些功能函数。
  4. 需要运算符的优先级关系所定义的功能函数。

优先级关系表:

    右

                 左

+

-

*

/

(

)

#

+

>

>

<

<

<

>

>

-

>

>

<

<

<

>

>

*

>

>

>

>

<

>

>

/

>

>

>

>

<

>

>

(

<

<

<

<

<

=

)

>

>

>

>

>

>

#

<

<

<

<

<

=

优先级分析:

优先级函数代码:

//比较运算符优先级 
char compare(char a,char b)
{
    if(a=='+'||a=='-')                //a为 + - 时  
    {
        if(b=='+'||b=='-'||b==')'||b=='#')  return '>';
        else   return '<';
    }
    else if(a=='*'||a=='/')            //a为 * / 时
    {
        if(b=='(') return '<';
        else  return '>';
    }
    else if(a=='(')                    //a为( 时 
    {
        if(b=='+'||b=='-'||b=='*'||b=='/'||b=='(') return '<';
        else if(b==')')  return '=';
             else{
            printf("输入有误");
            return 0;
        	}
    }
    else if(a==')')                    //a为 ) 时 
    {
        if(b=='+'||b=='-'||b=='*'||b=='/'||b==')'||b=='#') return '>';
        else if(b=='(')
        {
            printf("输入有误");
            return 0;
        }
    } 
    else if(a=='#') 				//a为 # 时 
    {
        if(b==')')
        {
            printf("输入有误");
            return 0;
        }
        else if(b=='#')  return '=';
             else return '<';
    }
}

二、实操

分析:

  如果是操作数,则直接进栈,并依次读入下一个。

  如果是运算符,则先与符号栈top做优先级比较,做以下处理:

  1. 如果读入的优先级>top,则进栈。
  2. 如果读入的优先级=top,则括号相遇,运算符栈顶退栈。
  3. 如果读入的优先级<top,则在操作数栈中连续退两个(符号邻近的两个),符号栈退一个,进行运算。
  4. 如果读入为结束符'#',则表达式处理完毕,通过循环和分支来计算栈中存在的值。

具体代码:

//运算符 初始化
 int Initsign(fustack &s){
 	s=(FUStack *)malloc(sizeof(FUStack));
 	s->top=-1;
 	if(s==NULL){
 		return false;
	 }else{
	 	return true;
	 }
 }
//操作数 初始化
int Initshu(shustack &s){
	s=(SHUStack *)malloc(sizeof(SHUStack));
 	s->top=-1;
 	if(s==NULL){
 		return false;
	 }else{
	 	return true;
	 }
} 
//运算符入栈
 int pushfu(fustack &s,char c){
 	if(s->top==max-1){
 		printf("栈满!");
 		return false;
	 }else{
        s->top++;
        s->data[s->top]=c;
        return true;
	 }
 } 
//操作数 入栈
 int pushshu(shustack &s,int x){
 	if(s->top==max-1){
 		printf("栈满!");
 		return false;
	 }else{
        s->top++;
        s->data[s->top]=x;
        return true;
	 }
 } 
//运算符 出栈
 char popfu(fustack &s,char &a)
{
    if(s->top==-1){
  		printf("栈空fu!");
        return false;	
	}else{
		a= s->data[s->top];
        s->data[s->top]=0;
        s->top--;
        return a;
    }
}
//操作数 出栈
int popshu(shustack &s,int &x){
	if(s->top==-1){
		printf("栈空shu!");
		return false;
	}else{
		x=s->data[s->top];
		s->data[s->top]=0;
		s->top--;
		return x;
	}
} 
//运算符 取栈顶
 char getfutop(fustack s){
 	if(s->top==-1){
		printf("栈空fu!");
		return false;
	}else{
		return s->data[s->top];	
	}
 } 
//操作数 取栈顶
 int getshutop(shustack s){
 	if(s->top==-1){
		printf("栈空shu!");
		return false;
	}else{
		return s->data[s->top];	
	}
 }
//计算函数  f为运算符的top元素 
 int operate(int a,char f,int b)    
{
    if(f=='+'){
		return a+b;
	}else if(f=='-'){
		return a-b;	
	}else if(f=='*'){
		return a*b;
	}else if(f=='/'){
		 return a/b;
	}
}

//这里定义的只适用于10以内的加减乘除
/*     getfutop:取符号栈栈顶    getshutop:取操作数栈栈顶
       popfu:符号栈出栈        popshu:操作栈出栈
       pushfu:符号栈入栈        pushshu:操作栈入栈
       Initsign:初始化符号栈   Initshu:初始化操作数栈
*/

int main(){
	shustack s;  //数栈 
	fustack  f;  //符号栈 
	Initshu(s);
	Initsign(f);
	int a,b,data;
	char F,F1;
	pushfu(f,'#');         //运算符栈以'#'压栈 
	char ch=getchar();     //取元素
	while(ch!='#'||getfutop(f)!='#'){     //当取到的元素和 运算符top值不为‘#’
		 if(ch>='0'&&ch<='9')             //如果为操作数
		 {
		 	data=ch-'0';                  //这里是将读入的操作数转换为十进制
		 	pushshu(s,data);              //操作数进栈
		 	ch=getchar();                 //重新取值
		 }	
		else{                             //如果不为操作数
	    	switch(compare(getfutop(f),ch))  //compare函数是比较符号栈top指针和ch取到的符号的优先级
			{
	        	case'<':pushfu(f,ch);     //如果优先级<  符号进栈
		 		ch=getchar();break;       //重新取
		 	
		 		case'=':popfu(f,F);      //如果优先级 =  符号出栈(代表有左右括号)
		 		ch=getchar();break;      //重新取
		 	
		 		case'>':                 //如果优先级>  
				popfu(f,F1);             //出符号栈top赋值给F1
				popshu(s,b);             //出操作数赋值给b
				popshu(s,a);            //出操作数赋值给a
				int q=operate(a,F1,b);  //计算a,F1,b 的值赋给q
		 		pushshu(s,q);            //q进操作数栈
		 		break;
		 	}
		 	} 
			 	
		}
		int shuzhi=getshutop(s);       //取操作数栈顶元素
		 	printf("%d",shuzhi);        //输出
	} 

运行结果:

1.不带括号:

 2.带括号:

程序能run,需要的可以直接复制下来,代码规范可能不太好,每个函数的意思在main函数前已经标识,望大家谅解!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

犀牛超人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值