专门用来对付运算式子的一个算法

例如我们做到一个计算器的时候我们会遇到1+9+6/8类似这种,那么我们就可以用把这个式子变成后缀表达式然后再来计算。


struct//设定运算符的优先级 
{
	char ch;//运算符 
	int pri;//优先级 
}lpri[] = { { '=', 0 }, { '(', 1 }, { '*', 5 }, { '/', 5 }, { '+', 3 }, { '-', 3 }, { ')', 6 } },
rpri[] = { { '=', 0 }, { '(', 6 }, { '*', 4 }, { '/', 4 }, { '+', 2 }, { '-', 2 }, { ')', 1 } };
int leftpri(char op)//左边运算符的优先级 
{
	int i;
	for (i = 0; i<7; i++)
	if (lpri[i].ch == op)return lpri[i].pri;
}
int rightpri(char op)//右运算符的优先级 
{
	int i;
	for (i = 0; i<7; i++)
	if (rpri[i].ch == op)
		return rpri[i].pri;
}
bool InOp(char ch)//判断ch是不是运算符 
{
	if (ch == '(' || ch == ')' || ch == '+' || ch == '-' || ch == '*' || ch == '/')
		return true;
	else
		return false;
}
int Precede(char op1, char op2)//op1和op2运算符的优先级情况 
{
	if (leftpri(op1) == rightpri(op2))
		return 0;
	if (leftpri(op1)<rightpri(op2))
		return -1;
	else
		return 1;
}
void trans(char *exp, char postexp[])//将一般的表达式转成后缀表达式 
{
	struct //存放运算符 
	{
		char data[1000];
		int top;//栈指针 
	}op;
	int i = 0;
	op.top = -1;
	op.top++;
	op.data[op.top] = '=';
	while (*exp != '\0')//exp表达式未扫描完时循环 
	{
		if (!InOp(*exp))//若是数字的时候 
		{
			while (*exp >= '0'&&*exp <= '9')//判断为数字 
			{
				if (*(exp - 2) == '(' && (*(exp - 1) == '+' || *(exp - 1) == '-' || *(exp - 1) == '*' || *(exp - 1) == '/'))//是是负数的符号而不是减号 
				{
					postexp[i++] = '&';//这个是为了处理负数的情况,如果是负数则会出现&和数字 例如&5 
					int a = i + 1;
					postexp[a++] = *exp;
				}
				postexp[i++] = *exp;
				exp++;//存放表达式 
			}
			postexp[i++] = '#';//用一个#号隔开 
		}
		else//如果是运算符的情况                         
		{
			if ((*exp == '+' || *exp == '-' || *exp == '*' || *exp == '/') && *(exp - 1) == '(' && (*(exp + 1) >= '0'&&*(exp + 1) <= '9'))//除掉是负数的-号 
			{
				exp++;
				continue;
			}
			else
			{
				switch (Precede(op.data[op.top], *exp))
				{
				case -1://栈顶运算符的优先级低 
					op.top++;
					op.data[op.top] = *exp;
					exp++;
					break;
				case 0://只有括号满足这种情况 
					op.top--;
					exp++;
					break;
				case 1://退栈并输入到postexp数组中 
					postexp[i++] = op.data[op.top];
					op.top--;
					break;
				}
			}
		}

	}
	while (op.data[op.top] != '=')//此时已经扫描好了,退栈到'='结束 
	{
		postexp[i++] = op.data[op.top];
		op.top--;
	}
	postexp[i] = '\0';//添加一个结束标志 
}
float compvalue(char *postexp)//通过后缀表达式开始计算值 
{
	struct
	{
		float data[1000];//存放数字的数组 
		int top;
	}st;
	float d, a, b, c;
	st.top = -1;
	while (*postexp != '\0')//当postexp字符串为扫描完时 
	{
		switch (*postexp)
		{
		case '+'://判断是'+’的时候 
			a = st.data[st.top];
			st.top--;
			b = st.data[st.top];
			st.top--;
			c = a + b;
			st.top++;
			st.data[st.top] = c;//这就是计算两个数字相加的时候a,b退栈计算c然后进栈 
			break;


		case '-':
			a = st.data[st.top];
			st.top--;
			b = st.data[st.top];
			st.top--;
			c = b - a;
			st.top++;
			st.data[st.top] = c;
			break;



		case '*':
			a = st.data[st.top];
			st.top--;
			b = st.data[st.top];
			st.top--;
			c = b*a;
			st.top++;
			st.data[st.top] = c;
			break;


		case '/':
			a = st.data[st.top];
			st.top--;
			b = st.data[st.top];
			st.top--;
			if (a != 0)
			{
				c = b / a;
				st.top++;
				st.data[st.top] = c;
			}
			else
			{
				printf("error(分母为0)\n");
				exit(0);
			}
			break;
		default:
			d = 0;
			int find = 0;
			while (*postexp >= '0'&&*postexp <= '9'&&*postexp != '&')
			{
				if (*(postexp - 1) == '&')
				{
					find = 1;
				}
				else
				{
					find = -1;
				}
				d = 10 * d + *postexp - '0';
				postexp++;
			}

			if (find == 1)
			{
				st.top++;
				st.data[st.top] = -d;
			}
			else if (find == -1)
			{
				st.top++;
				st.data[st.top] = d;
			}
			break;

		}
		postexp++;
	}
	return(st.data[st.top]);//最后指针指的位置就是值 
}

这个是c++版本的 ,现在正在把这个做成java包以后专用使用

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。