表达式求值(中缀表达式转换为后缀表达式)

        上一篇文章是后缀表达式求值,由于后缀表达式不是我们人类能接受的求值表达式,so本文为中缀表达式转换为后缀表达式的方法。然后再结合上一篇逆波兰表达式,我们就可以利用中缀表达式求值啦!!!!本文的代码依然可以计算带小数点,大于10的数字的表达式!


思路:

一、遇到数字,直接存入字符串中。

二、遇到的是表达式符号(+,-,*,/,(,)):

1、如果栈为空,或者表达式为左括号‘(’,直接压入栈中;

2、做出栈操作,出栈元素存入c1,与待输入的符号c2进行比较,如果c1的优先级高于c2,则将c1存到结果字符串结尾,跳转到第1条,重新判断!

三、比较完毕后,将栈中剩余的元素弹出存到结果字符串的尾部!


关于栈的声明与定义就不再赘述,直接进入代码:

void toPolish()
{
	SqStack s;
	StackInit(&s);
	char c;
	char str[100];			//用于存储后缀表达式的结果字符串
	int i=0;			//字符数组下标,初始化为0


	printf("请输入正确的中缀表达式,以#结束输入。\n");
	
	scanf("%c",&c);


	while (c!='#')
	{
		if (isdigit(c) || c=='.')		
		{/*大于10的数位数之间不能有空格,所以先做判断再循环,循环结束后加空格,结尾在赋'\0'*/
			while(isdigit(c) || c=='.')
			{
				str[i++]=c;
				scanf("%c",&c);
			}
			str[i++]=' ';
			str[i]='\0';
		}
		if(c=='#')break;	/*如果数字之后是#的话,此处判断才是大循环的结束之处,否则在循环结束后再输入会造成死循环,不理解可以下断点试试*/
		if (c=='(')		//右括号直接压栈
		{
			Push(&s,c);
		}
		if (c==')')		//左括号则做出栈并赋给结果字符串中,再将有括号也弹出栈。
		{
			while(*(s.top)!='(')
			{
				Pop(&s,&str[i]);
				i++;
				str[i++]=' ';
				str[i]='\0';
			}
			char temp;
			Pop(&s,&temp);
		}
		if (c=='+' || c== '-' || c=='*' || c=='/')	//判断是否为符号,封装起来也许更我,我没做而已
		{
			if (s.top-s.base==0 || *(s.top)=='(')	//如果空栈或栈顶为(,入栈
			{
				Push(&s,c);
			}
			else
			{
				char temp;		
				Pop(&s,&temp);
				if (judge(temp,c))		//重点,判断栈顶和当前的符号优先级,并左相应操作,相关代码在后面
				{
					str[i++]=temp;
					str[i++]=' ';
					str[i]='\0';
					continue;
				} 
				else
				{
					Push(&s,temp);
					Push(&s,c);
				}
			}
		}


		scanf("%c",&c);
	}


	while (s.top-s.base>0)		//把栈中剩余元素赋给结果数组
	{
		Pop(&s,&str[i]);
		i++;
		str[i++]=' ';
		str[i]='\0';
	}


	str[i++]='#';
	str[i]='\0';


	puts(str);
	system("pause");
	return 0;
}


这个函数是用来判断c1 与c2谁的优先级更高,true代表c1>c2,false代表c1<c2;

方法挺傻的,copy一下倒是蛮方便,呵呵!

//判断表达式符号(+ - * /)c1,c2的优先级,有人用数组的方式左,反正就是个方法而已无所谓!
bool judge(char c1,char c2)
{
	switch(c1)
	{
	case '+':
		{
			switch(c2)
			{
			case '+':
				return true;
			case '-':
				return true;
			case '*':
				return false;
			case '/':
				return false;
			}
		}
	case '-':
		{
			switch(c2)
			{
			case '+':
				return true;
			case '-':
				return true;
			case '*':
				return false;
			case '/':
				return false;
			}
		}
	case '*':
		{
			switch(c2)
			{
			case '+':
				return true;
			case '-':
				return true;
			case '*':
				return true;
			case '/':
				return true;


			}
		}
	case '/':
		{
			switch(c2)
			{
			case '+':
				return true;
			case '-':
				return true;
			case '*':
				return true;
			case '/':
				return true;
			}
		}
	}
}

输出结果:

小结:表达式求值就到此结束了,不论哪个版本的数据结构,算法的参考资料里,学习栈时,表达式求值都是很经典的例子!它充分的利用了栈的原理进行操作!

当初刚接触栈时,表达式求值对我来说简直是个噩梦!过来再看,对栈的理解更深刻了!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
表达式求值是指将一个数学表达式中的数字和运算符进行计算的过程。在计算机中,表达式求值通常采用中缀表达式后缀表达式的方式进行。中缀表达式是指运算符位于两个操作数之间的表达式,例如:3 + 4 * 5。而后缀表达式是指运算符位于操作数之后的表达式,例如:3 4 5 * +。将中缀表达式转换后缀表达式的过程中,需要使用栈来存储运算符,并按照一定的规则进行出栈和入栈操作,最终得到后缀表达式后缀表达式的计算比较简单,只需要按照操作符从左到右的顺序依次执行即可。 在C语言中,可以使用栈来实现中缀表达式后缀表达式的过程。具体步骤如下: 1. 初始化一个字符栈和一个后缀表达式字符串。 2. 从左到右遍历中缀表达式的每个字符。 3. 如果当前字符是数字,则直接将其添加到后缀表达式字符串中。 4. 如果当前字符是左括号,则将其入栈。 5. 如果当前字符是右括号,则将栈中的字符依次出栈并添加到后缀表达式字符串中,直到遇到左括号为止。 6. 如果当前字符是运算符,则将栈中优先级大于等于该运算符的字符依次出栈并添加到后缀表达式字符串中,然后将该运算符入栈。 7. 重复以上步骤直至遍历完成中缀表达式。 8. 判断字符栈是否为空,非空则直接出栈,并将出栈字符依次送入后缀表达式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值