输入一个四则运算,计算其结果

一般我们所输入的四则运算都是中缀四则运算,如:9+(3-1)*3+10/2,为了便于计算机处理,在计算四则运算的时候,往往先将中缀四则运算改为后缀四则运算。

这里 先介绍下后缀四则运算的原理,主要是运用了栈的后进先出,这里首先需要一个栈用来保存运算符:

中缀转后缀的原理:

首先是9,直接保存到数组中,然后是+,直接进栈,然后是(,直接进栈,再就是3,保存到数组中,然后是-,因为栈顶为(,所以直接进栈,然后是),此时从栈顶开始依次将符号保存到数组中,直到遇到(为止,然后是*,因为此时栈中只有+,优先级低于*,所以*直接进栈,然后是3,直接进入数组,然后是+,因为本栈中不可能还有比+更低的优先级了,所以先从栈顶开始将符号保存到数组,然后将+进栈,然后是10,直接进数组,再就是/,由于栈中此时只有+,所以直接进栈,然后是2,直接进数组,最后将栈中的符号从栈顶开始依次保存到数组中,此时得到的后缀表达式结果为:9  3 1 - 3 *+ 10 2 /+

注意事项:

1.数字直接进入保存后缀结果的数组中;

2.遇到‘(’,直接保存到栈中;

3.遇到‘)’,则依次遍历栈中的符号,并保存到数组中,知道遇到'('为止,且'('不用保存到数组中;

4.加入符号进栈的规则是:如果栈中的优先级不低于当前符号的优先级,则先将栈中的符号出栈,并保存到数组,然后将当前符号进栈;否则,直接进栈。

计算机计算后缀表达式的原理

前面我们得到的后缀表达式为:9  3 1 - 3 *+ 10 2 /+。在中缀转后缀的过程中,我们是将符号存在栈中,这里计算后缀表达式则是将数字保存在栈中,还是运用了栈的后进先出原理。

第一个数字是9,直接进栈,然后是3,直接进栈,数字1,直接进栈,然后是符号'-',这里则取出战中的栈顶的数字和栈顶下面的数字,然后用栈顶下面的数字3,减去栈顶的数字1,得到2,然后将之前的栈顶下移,然后保存2,此时栈中保存9  2,然后是3,直接进栈,此时栈中保存9  2  3;然后是*,此时取出2和3,用2*3,得到6,然后将栈顶下移一位,保存6,栈中保存9  6,然后是+,此时取出9和6,得到15,将栈顶下移一位,保存15,此时栈中只有15,再是10,直接进栈,然后是2,直接进栈,此时栈中保存15   10   2,然后是'/',取出栈中的10和2,用10除以2,得到5,然后栈顶下移一位,保存5,最后栈中保存15   5,最后是符号+,取出栈中15和5,用15加上5,得到10,然后将栈顶下移一位,保存20,最后20是最终结果。

注意事项:

1.数字直接进栈;

2.遇到符号,取出栈中的前两位,用上一位和栈顶进行运算,然后栈中保存结果到上一位,栈顶下移一位;

3.最后栈顶的结果就是最后结果。

下面提供一个程序代码:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 99

//将中缀表达式转换成后缀表达式
void translate(char str[], char exp[])//将中缀表达式转换为后缀表达式
{
	struct 
	{
		char data[MaxSize];
		int top; //top为栈顶
	}op;
	char ch;
	int i = 0;
	int t = 0;
	op.top = -1;
	ch = str[i];
	i++;
	while (ch != '\0')
	{
		switch (ch)
		{
		case '(':
			op.top++;
			op.data[op.top] = ch;
			break;
		case ')':
			while (op.data[op.top] != '(')
			{
				exp[t] = op.data[op.top];
				t++;
				op.top--;
			}
			op.top--;
			break;
		case '+':
		case '-':
			while (op.top != -1 && op.data[op.top] != '(')
			{
				exp[t] = op.data[op.top];
				op.top--;
				t++;
			}
			op.top++;
			op.data[op.top] = ch;
			break;
		case '*':
		case '/':
			while (op.top != -1 && (op.data[op.top] == '/' || op.data[op.top] == '*'))
			{
				exp[t] = op.data[op.top];
				op.top--;
				t++;
			}
			op.top++;
			op.data[op.top] = ch;
			break;
		case ' ':  //忽略空隔,排除误操作
			break;
		default:
			while (ch >= '0' && ch <= '9')
			{
				exp[t] = ch;
				t++;
				ch = str[i];
				i++;
			}
			i--;
			exp[t] = '#';//分隔符,分隔操作数
			t++;	
		}
		ch = str[i];
		i++;
	}
	//得到剩下部分
	while (op.top != -1)
	{
	     exp[t] = op.data[op.top];
	     t++;
	     op.top--;
	}
	exp[t] = '\0';
}

//计算机计算后缀表达式
float cal_value(char exp[])
{
	struct 
	{
	    float data[MaxSize];
	    int top;
	}st;       //操作数
	float d;
	char ch;
	int t = 0;
	st.top = -1;
	ch = exp[t];
	t++;
	while (ch != '\0')
	{
		switch (ch)   //运算主体
		{
		case '+':
			st.data[st.top - 1] = st.data[st.top - 1] + st.data[st.top];
			st.top--;
			break;
		case '-':
			st.data[st.top - 1] = st.data[st.top - 1] - st.data[st.top];
			st.top--;
			break;
		case '*':
			st.data[st.top - 1] = st.data[st.top - 1] * st.data[st.top];
			st.top--;
			break;
		case '/':
			if (st.data[st.top] != '0')
			{
				st.data[st.top - 1] = st.data[st.top - 1] / st.data[st.top];
			}
			else
			{
				printf("\n\t除0是错误的!");
			}
			st.top--;
			break;
		default:
			d = 0;
			while (ch >= '0' && ch <= '9')
			{
				d = d * 10 + ch - '0';
				ch = exp[t];
				t++;
			}
			st.top++;
			st.data[st.top] = d;
		}
		ch = exp[t];
		t++;
	}
	return st.data[st.top];
}
int _tmain(int argc, _TCHAR* argv[])
{
	char str[MaxSize], exp[MaxSize];
	printf("请输入一个求值表达式:\n");
	gets_s(str);
	printf("原表达式是:%s\n", str);
	translate(str, exp);
	printf("后缀表达式为:%s\n", exp);
	printf("计算后的结果为:%f\n", cal_value(exp));
	system("pause");
	return 0;
}

  

 

posted on 2016-04-29 15:00  !!-阳光-!!  阅读(1098)  评论(0编辑  收藏  举报

导航