表达式求值
因工作需要对表达式求值,借机巩固下基础知识,使用两个栈,一个存放操作数,一个存放算符。
在表达式的开始和结尾分别放一个#,表示开始和结束。
算符栈初始的时候有一个#算符,如果是计算1+2,这里会有一个疑问,1入栈后,读到算符+,
(当前的算符)其优先级比 栈顶算符# 大,也就是栈顶算符优先级低,则需要把该算符入栈。
下一个算符是#,其优先级比栈顶算符+的小,栈顶算符优先级大,则将两个操作数出栈和栈顶算符出栈,进行运算。
如果计算表达式1+2+3*4。
1入栈后,读到算符+,
(当前的算符)其优先级比 栈顶算符# 大,也就是栈顶算符优先级低,则需要把该算符入栈。
下一个算符是+,其优先级和栈顶算符优先级相等,这里会有一个疑问,根据则将栈顶算符出栈,并去取下一个字符。(错误)
这里把栈顶的+出栈,当前算符+也没有入栈,栈顶算符变成了#。 +算符都没有了,可怎么办?
读取下一个字符是3,操作数里面有1 2 3
读取到*,比栈顶算符优先高,栈顶算符优先级低,则入栈。
读取最后一个算符#,栈顶算符优先级高,则进行计算:3*4 。
正确的运算过程是:
1入栈后,读到算符+,
(当前的算符)其优先级比 栈顶算符# 大,也就是栈顶算符优先级低,则需要把该算符入栈。
下一个算符是+,其优先级和栈顶算符优先级相等,根据运算法则,同级别时,先左后右。应该将栈顶算符和两个操作数取出,进行计算,然后将当前字符和运算结果入栈。
支持+-*/运算的代码:
public class ExpCaculate
{
Stack<int> optd = new Stack<int>();
Stack<char> optr = new Stack<char>();
public void run(string exp)
{
optr.Push('#');
Console.WriteLine("计算表达式:" + exp);
for (int i = 0; i < exp.Length; i++)
{
char ch = exp[i];
// 识别0-9数字
if (IsNumer(ch))
{
// 从表达式里面提取数字
StringBuilder d = new StringBuilder();
d.Append(ch);
for (int j = i+1; j < exp.Length; j++)
{
if (IsNumer(exp[j]))
{
d.Append(exp[j]);
i = j;
}
else
{
break;
}
}
int t = int.Parse(d.ToString());
optd.Push(t);
}
else if (IsOptr(ch))
{
switch (Percede(ch))
{
case ">": //当前算符优先级高, 栈顶算符优先级低
optr.Push(ch);
break;
case "<":
case "=":
int a = optd.Pop();
int b = optd.Pop();
char theta = optr.Pop();
int r = Caclulae(a, b, theta);
optd.Push(r);
optr.Push(ch);
break;
default:
break;
}
}
}// end for
optr.Pop();
while (optr.Count > 1&&optd.Count>1)
{
int a = optd.Pop();
int b = optd.Pop();
char theta = optr.Pop();
int r = Caclulae(a, b, theta);
optd.Push(r);
}
if (optd.Count == 1)
{
Console.WriteLine("计算结果是:" + optd.Pop());
optr.Clear();
optd.Clear();
}
else
{
Console.WriteLine("error :");
}
}
private int Caclulae(int a, int b, char theta)
{
switch (theta){
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
}
return 0;
}
private string Percede(char ch)
{
if (optr.Count == 0)
{
return "";
}
char top = optr.Peek();
switch (top)
{
case '+':
case '-':
if (ch == '*' || ch == '/')
{
return ">";
}
else if (ch == '+' || ch == '-')
{
return "=";
}
else
{
return "<";
}
case '*':
case '/':
if (ch == '*' || ch == '/')
{
return "=";
}
else if (ch == '+' || ch == '-')
{
return "<";
}
else
{
return "<";
}
case '#':
if (ch == '#')
{
return "=";
}
else
{
return ">";
}
}
return "=";
}
private bool IsOptr(char ch)
{
return ch == '+' || ch == '-' || ch == '*' || ch == '/'|| ch == '#';
}
public bool IsNumer(char ch)
{
return ch > 47 && ch < 58;
}
}

浙公网安备 33010602011771号