算法基础系列之四:表达式计算及逆波兰栈

简单的表达式计算及逆波兰栈

今天Boss不在,可以偷偷玩会。想写一个程序计算一个字符串表达式(假定表达式合法),使用逆波兰栈的原理。一开始觉得很容易,写了一会倒也出了不少问题,好在都是些小问题。

1.在字符串拆分那块就琢磨半天,也没想出什么好方法,最后用很土的方法实现的(方法StringSplit

2.发现老是要判断符号栈是否有元素,干脆先压入一个“$”(operStack.Push("$")),类似“哨兵”。

3.遇到类似“-15*2+3*(1+2)”这样的式子时出错,所以在数字栈中先压入0numStack.Push(0)

4.为了在扫描字符串结束后自动弹出符号栈中的符号并计算,在原字符末加上“$”,让程序在遇“$”时弹出所有符号。

程序如下,错误的或都不好的地方大家多多批评,感谢:

 

private static Regex regOper = new Regex(@"[\+\-\*/\(\)$]");
static void Main(string[] args)

    
string expression = Console.ReadLine();
    Stack
<double> numStack = new Stack<double>();
    Stack
<string> operStack = new Stack<string>();
    numStack.Push(
0);
    operStack.Push(
"$");

    List
<string> list = StringSplit(expression);
    
string oper = "";
    
foreach (string element in list)
    
{
        
if (regOper.IsMatch(element))
        
{
            
switch (element)
            
{
                
case "+":
                
case "-":
                    
while ((oper = operStack.Pop()) != "$" && oper != "(")
                    
{
                        
double temp = Cal(numStack.Pop(), numStack.Pop(), oper);
                        numStack.Push(temp);
                    }

                    operStack.Push(oper);
                    operStack.Push(element);
                    
break;
                
case "*":
                
case "/":
                    
while ((oper = operStack.Pop()) == "*" || oper == "/")
                    
{
                        
double temp = Cal(numStack.Pop(), numStack.Pop(), oper);
                        numStack.Push(temp);
                    }

                    operStack.Push(oper);
                    operStack.Push(element);
                    
break;
                
case "(":
                    operStack.Push(element);
                    
break;
                
case ")":
                    
while ((oper = operStack.Pop()) != "(")
                    
{
                        
double temp = Cal(numStack.Pop(), numStack.Pop(), oper);
                        numStack.Push(temp);
                    }

                    
break;
                
default:
                    
while ((oper = operStack.Pop()) != "$")
                    
{
                        
double temp = Cal(numStack.Pop(), numStack.Pop(), oper);
                        numStack.Push(temp);
                    }

                    
break;
            }

        }

        
else
        
{
            numStack.Push(Convert.ToDouble(element));
        }

    }

    Console.WriteLine(
"表达式结果:" + numStack.Pop());
    Console.Read();
}


//拆分表达式
static List<string> StringSplit(string s)
{
    List
<string> list = new List<string>();
    
int position = -1;
    s 
+= "$";
    
for (int i = 0; i < s.Length; i++)
    
{
        
if (regOper.IsMatch(s[i].ToString()))
        
{
            
if (i - position > 1)
            
{
                list.Add(s.Substring(position 
+ 1, i - position - 1));
            }

            list.Add(s.Substring(i, 
1));
            position 
= i;
        }

    }

    
return list;
}


//计算两个数值的运算结果
static double Cal(double num1, double num2, string oper)
{
    
switch (oper)
    
{
        
case "+":
            
return num2 + num1;
        
case "-":
            
return num2 - num1;
        
case "*":
            
return num2 * num1;
        
case "/":
            
return num2 / num1;
        
default:
            
return 0;
    }

}

 

posted @ 2006-11-15 20:59  后厂村思维导图馆  阅读(1293)  评论(0编辑  收藏  举报