解决逆波兰表达式的计算就非常简单了,它只用到一个栈就可以搞定。
源代码如下:
/// <summary>
/// 解逆波兰表达式
/// </summary>
/// <param name="Expression">标准逆波兰表达式</param>
/// <returns>逆波兰表达式的解</returns>
public double ComplieRpnExp(string Expression)
{
try
{
//拆分逆波兰表达式
string[] strNum = Expression.Split(new char[] { ',' });
int intLenth = strNum.GetLength(0);
//定义数字堆栈
Stack number = new Stack();
for (int i = 0; i < intLenth; i++)
{
int intLevel = this.OperatorLevel(strNum[i]);
if (intLevel == -1)
{
//如果为数字则直接压入数字堆栈
number.Push(Convert.ToDouble(strNum[i]));
}
else if (intLevel > 2)
{
//为符号则将数字堆栈后两个数据解压并计算,将计算结果压入堆栈
if (number.Count > 1)
{
//必须保证数字堆栈有2个以上数字
double dLastin = Convert.ToDouble(number.Pop());
double dFirstin = Convert.ToDouble(number.Pop());
double dResult = this.ComplieRpnExp(dLastin, dFirstin, strNum[i]);
if (!Convert.IsDBNull(dResult))
{
//压入计算结果
number.Push(dResult);
}
}
}
}
double d = Convert.ToDouble(number.Pop());
number.Clear();
return d;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
return 0;
}
}
/// <summary>
/// 计算逆波兰表达式
/// </summary>
/// <param name="dLastin">最后压入数字堆栈的数字</param>
/// <param name="dFirstin">首先压入数字堆栈的数字</param>
/// <param name="oper">操作运算符</param>
/// <returns>返回计算结果</returns>
private double ComplieRpnExp(double dLastin, double dFirstin, string oper)
{
switch (oper)
{
case "+":
return dFirstin + dLastin;
case "-":
return dFirstin - dLastin;
case "*":
return dFirstin * dLastin;
case "/":
return dFirstin / dLastin;
default:
return 0;
}
}
到此逆波兰表达式已经全部搞定,现在我可以通过将中缀表达式转换成逆波兰表达式再计算,不会担心括号的问题。
一元多次方程乃至一元多次方程的解都迎刃而解。