您的位置:首页 > 其它

中缀转后缀并计算

2016-03-10 10:37 302 查看
如有问题,请各位大虾指正

public class Analyze
{

private Stack<string> stack;//存运算符
private ArrayList post;//存后缀表达式
private Stack<float> result;//存计算结果

public Analyze()
{
stack = new Stack<string>();
post = new ArrayList();
result = new Stack<float>();
}

public float Calculate(string expression)
{
ArrayList items = getItem(expression);
Merger(items);
return Sum();
}

#region 获得分解后的list
private ArrayList getItem(string expression)
{
string lastNum = string.Empty;
ArrayList items = new ArrayList();
for (int i = 0; i < expression.Length; i++)
{
if (char.IsNumber(expression[i]) || expression[i].Equals('.'))
{
lastNum += expression[i];
}
else
{
if (lastNum != string.Empty)
{
items.Add(lastNum);
lastNum = string.Empty;
}
items.Add(expression[i]);
}
}
if (lastNum != string.Empty)
{
items.Add(lastNum);
lastNum = string.Empty;
}
return items;
}
#endregion

#region 转换成后缀表达式
/**
* 从左到右扫描中缀表达式:
* (1)若读到的是操作数,直接存入post栈
* (2)若读到的是(,则直接存入stack栈
* (3)若读到的是),则将stack栈中(前的所有运算符出栈,存入post栈
* (4)若读到的是其它运算符,则将该运算符和stack栈顶运算符作比较:若高于或等于栈顶运算符,
* 则直接存入stack栈,否则将栈顶运算符(所有优先级高于读到的运算符的,不包括括号)出栈,存入post栈。
* 最后将读到的运算符入栈。
* 当扫描完后,stack栈中还在运算符时,则将所有的运算符出栈,存入post栈
*/
private void Merger(ArrayList items)
{
foreach (var o in items)
{
string item = o.ToString();
if (Regex.IsMatch(item, @"^(([1-9][0-9]*\.[0-9][0-9]*)|([0]\.[0-9][0-9]*)|([1-9][0-9]*)|([0]{1}))$"))
{
post.Add(item);
continue;
}
if (item.Equals("("))
{
stack.Push(item);
continue;
}
if (item.Equals(")"))
{
while (!stack.Peek().Equals("("))
{
post.Add(stack.Pop());
}
stack.Pop();
continue;
}
if (item.Equals("+") || item.Equals("-") || item.Equals("*") || item.Equals("/"))
{
if (stack.Count == 0)
{
stack.Push(item);
continue;
}
string tempStack = stack.Peek();
if (((item.Equals("*") || item.Equals("/")) &&
(tempStack.Equals("+") || tempStack.Equals("-")))||tempStack.Equals("("))
{
stack.Push(item);
}
else
{
post.Add(stack.Pop());
stack.Push(item);
}
continue;
}
}
while (stack.Count>0)
{
post.Add(stack.Pop());
}
}
#endregion

#region 后缀表达式计算值
/**
* 从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,
* 遇到是符号,就将处于栈顶两个数字出栈,
* 进行运算,运算结果进栈,一直到最终获得结果。
*/
private float Sum()
{
float re = 0;
foreach(string item in post){
if (Regex.IsMatch(item, @"^(([1-9][0-9]*\.[0-9][0-9]*)|([0]\.[0-9][0-9]*)|([1-9][0-9]*)|([0]{1}))$"))
{
result.Push(float.Parse(item));
continue;
}
if (item.Equals("+") || item.Equals("-") || item.Equals("*") || item.Equals("/"))
{
float num1 = result.Pop();
float num2 = result.Pop();
switch (item)
{
case "+":
re = num2 + num1;
break;
case "-":
re = num2 - num1;
break;
case "*":
re = num2 * num1;
break;
case "/":
re = num2 / num1;
break;
}
result.Push(re);
continue;
}
}
return result.Pop();
}
#endregion
}


View Code
程序展现:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: