逆波兰式求表达式

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Windows.Forms;

namespace CaculateExpression
{
///


/// 表达式计算器
///

public class ExpressionEvaluator
{
#region 构造函数
///
///
///

private ExpressionEvaluator()
{
}
#endregion

#region 分析表达式

///
/// 将算术表达式转换为逆波兰表达式
///

/// 要计算的表达式,如"1+2+3+4"
private static List ParseExpression(string expression)
{
if (string.IsNullOrEmpty(expression)) return null;

List listOperator = new List(10);
Stack stackOperator = new Stack(5);

ExpressionParser expParser = new ExpressionParser(expression);
ExpressionNode beforeExpNode = null; //前一个节点
ExpressionNode unitaryNode = null; //一元操作符
ExpressionNode expNode;

//是否需要操作数
bool requireOperand = false;

#region 分析表达式

while ((expNode = expParser.ReadNode()) != null)
{
if (expNode.Type == ExpressionNodeType.Numeric)
{
//操作数, 直接加入后缀表达式中
if (unitaryNode != null)
{
//设置一元操作符节点
expNode.UnitaryNode = unitaryNode;
unitaryNode = null;
}

listOperator.Add(expNode);
requireOperand = false;
}
else if (expNode.Type == ExpressionNodeType.LParentheses)
{
//左括号, 直接加入操作符栈
stackOperator.Push(expNode);
}
else if (expNode.Type == ExpressionNodeType.RParentheses)
{
//右括号则在操作符栈中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。
ExpressionNode lpNode = null;
while (stackOperator.Count > 0)
{
lpNode = stackOperator.Pop();
if (lpNode.Type == ExpressionNodeType.LParentheses) break;
listOperator.Add(lpNode);
}
if (lpNode == null || lpNode.Type != ExpressionNodeType.LParentheses)
{
MessageBox.Show(string.Format("在表达式\"{0}\"中没有与在

位置({1})上\")\"匹配的\"(\"字符!", expParser.Expression, expParser.Position));
return null;
}
}
else
{
if (stackOperator.Count == 0)
{
//第一个节点则判断此节点是否是一元操作符"+,-,!,("中的一个,否则其它都非法
if (listOperator.Count == 0 &&
!(expNode.Type == ExpressionNodeType.LParentheses || expNode.Type == ExpressionNodeType.Not))
{
//后缀表达式没有任何数据则判断是否是一元操作数
if (ExpressionNode.IsUnitaryNode(expNode.Type))
{
unitaryNode = expNode;
}
else
{
//丢失操作数
MessageBox.Show(string.Format("表达式\"{0}\"在位置({1})上缺少操作数!", expParser.Expression, expParser.Position));
return null;
}
}
else
{
//直接压入操作符栈
stackOperator.Push(expNode);
}
requireOperand = true; //下一个节点需要操作数
}
else
{
if (requireOperand)
{
//如果需要操作数则判断当前的是否是"+","-"号(一元操作符),如果是则继续
if (ExpressionNode.IsUnitaryNode(expNode.Type) && unitaryNode == null)
{
unitaryNode = expNode;
}
else
{
//丢失操作数
MessageBox.Show(string.Format("表达式\"{0}\"在位置({1})上缺少操作数!", expParser.Expression, expParser.Position));
return null;
}
}
else
{
//对前面的所有操作符进行优先级比较
do
{
//取得上一次的操作符
beforeExpNode = stackOperator.Peek();

//如果前一个操作符优先级较高,则将前一个操作符加入后缀表达式中
if (beforeExpNode.Type != ExpressionNodeType.LParentheses &&

(beforeExpNode.PRI - expNode.PRI) >= 0)
{
listOperator.Add(stackOperator.Pop());
}
else
{
break;
}

} while (stackOperator.Count > 0);

//将操作符压入操作符栈
stackOperator.Push(expNode);
requireOperand = true;
}
}
}
}

if (requireOperand)
{
//丢失操作数
MessageBox.Show(string.Format("表达式\"{0}\"在位置({1})上缺少操作数!", expParser.Expression, expParser.Position));
return null;
}
//清空堆栈
while (stackOperator.Count > 0)
{
//取得操作符
beforeExpNode = stackOperator.Pop();
if (beforeExpNode.Type == ExpressionNodeType.LParentheses)
{
MessageBox.Show(string.Format("表达式\"{0}\"中括号不匹配,丢失右括号!", expParser.Expression, expParser.Position));
return null;
}
listOperator.Add(beforeExpNode);
}
#endregion

return listOperator;
}

///


/// 对逆波兰表达式进行计算
///

///
///
private static object CalcExpression(List nodes)
{
if (nodes == null || nodes.Count == 0) return null;

#region 计算表达式
if (nodes.Count > 1)
{
int index = 0;
//储存数据
ArrayList values = new ArrayList();
while (index < nodes.Count)
{
ExpressionNode node = nodes[index];

switch (node.Type)
{
//如果是数字,则将值存入 values 中
case ExpressionNodeType.Numeric:
values.Add(node.Numeric);
index++;
break;
default:
//二元表达式,需要二个参数, 如果是Not的话,则只要一个参数
int paramCount = 2;
if (node.Type == ExpressionNodeType.Not) paramCount = 1;
//计算操作数的值
if (values.Count < paramCount)
{
MessageBo

x.Show("缺少操作数");
return null;
}
//传入参数
object[] data = new object[paramCount];
for (int i = 0; i < paramCount; i++)
{
data[i] = values[index - paramCount + i];
}
//将计算结果再存入当前节点
node.Numeric = Calculate(node.Type, data);
node.Type = ExpressionNodeType.Numeric;
//将操作数节点删除
for (int i = 0; i < paramCount; i++)
{
nodes.RemoveAt(index - i - 1);
values.RemoveAt(index - i - 1);
}
index -= paramCount;
break;
}
}
}

if (nodes.Count == 1)
{
switch (nodes[0].Type)
{
case ExpressionNodeType.Numeric:
return nodes[0].Numeric;
default:
MessageBox.Show("缺少操作数");
return null;
}
}
else
{
MessageBox.Show("缺少操作符或操作数");
return null;
}
#endregion
}

#region 计算节点的值
///


/// 计算节点的值
///

/// 节点的类型
/// 要计算的值,有可能是两位或一位数
///
private static object Calculate(ExpressionNodeType nodeType, object[] data)
{
decimal d1, d2;
bool b1, b2;
switch (nodeType)
{
case ExpressionNodeType.Plus:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return d1 + d2;
case ExpressionNodeType.Subtract:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return d1 - d2;
case ExpressionNodeType.MultiPly:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return d1 * d2;
case ExpressionNodeType.Divide:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
if (d2 == 0)throw new DivideByZeroException();
return d1 / d2;
case Expre

ssionNodeType.Power:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return Math.Pow((double)d1, (double)d2);
case ExpressionNodeType.Mod:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
if (d2 == 0) throw new DivideByZeroException();
return d1 % d2;
case ExpressionNodeType.BitwiseAnd:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return (int)d1 & (int)d2;
case ExpressionNodeType.BitwiseOr:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return (int)d1 | (int)d2;
case ExpressionNodeType.And:
b1 = ConvertToBool(data[0]);
b2 = ConvertToBool(data[1]);
return b1 && b2;
case ExpressionNodeType.Or:
b1 = ConvertToBool(data[0]);
b2 = ConvertToBool(data[1]);
return b1 || b2;
case ExpressionNodeType.Not:
b1 = ConvertToBool(data[0]);
return !b1;
case ExpressionNodeType.Equal:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return d1 == d2;
case ExpressionNodeType.Unequal:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return d1 != d2;
case ExpressionNodeType.GT:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return d1 > d2;
case ExpressionNodeType.LT:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return d1 < d2;
case ExpressionNodeType.GTOrEqual:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return d1 >= d2;
case ExpressionNodeType.LTOrEqual:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return d1 <= d2;
case ExpressionNodeType.LShift:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return (long)d1 << (int)d2;
case ExpressionNodeType.RShift:
d1 = ConvertToDecimal(data[0]);
d2 = ConvertToDecimal(data[1]);
return (long)d1 >> (int)d2;
default:
return 0;
}
}

#endregion

#region 数据转换
///


/// 将某个值转换为bool值
///

///
///
private static bool ConvertToBool(object value)
{
if (value is bool)
{
return (bool)value;
}
else
{
return Convert.ToDecimal(value) == 1;
}
}

///
/// 将某个值转换为decimal值
///

///
///
private static decimal ConvertToDecimal(object value)
{
if (value is bool)
{
return ((bool)value ? 1 : 0);
}
else
{
return Convert.ToDecimal(value);
}
}
#endregion


///
/// 对表达式进行计算
///

/// 要计算的表达式,如"1+2+3+4"
/// 返回计算结果,如果带有逻辑运算符则返回true/false,否则返回数值
public static object Eval(string expression)
{
if (ParseExpression(expression) != null)
return CalcExpression(ParseExpression(expression));
else
return null;
}
#endregion
}
}



















using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace CaculateExpression
{
///
/// 表达式的节点(如操作数或运算符)
///

public class ExpressionNode
{
///
/// 构造节点实例
///

/// 操作数或运算符
public ExpressionNode(string value)
{
this._Value = value;
this._Type = ParseNodeType(value);
this._PRI = GetNodeTypePRI(this.Type);
this._Numeric = null;
}

private string _Value;
///
/// 返回当前节点的操作数
///

public string Value
{
get
{
return _Value;
}
}

private ExpressionNodeType _Type;
///
/// 返回当前节点的类型
///

public ExpressionNodeType Type
{
get
{
return _Type;
}
internal set
{
_Type = value;
}
}

private int _PRI;
///
/// 返回当前节点的优先级
///

public int PRI

{
get
{
return _PRI;
}
}

private object _Numeric;
///


/// 返回此节点的数值
///

public object Numeric
{
get
{
if (_Numeric == null)
{
if (this.Type != ExpressionNodeType.Numeric) return 0;

decimal value = Convert.ToDecimal(this.Value);

if (this.UnitaryNode != null)
{
switch (this.UnitaryNode.Type)
{
case ExpressionNodeType.Subtract:
value = 0 - value;
break;
}
}

_Numeric = value;
}
return _Numeric;
}
internal set
{
_Numeric = value;
_Value = _Numeric.ToString();
}
}

private ExpressionNode _UnitaryNode;
///
/// 设置或返回与当前节点相关联的一元操作符节点
///

public ExpressionNode UnitaryNode
{
get
{
return _UnitaryNode;
}
set
{
_UnitaryNode = value;
}
}

#region 静态方法与属性
///
/// 解析节点类型
///

///
///
private static ExpressionNodeType ParseNodeType(string value)
{
if (string.IsNullOrEmpty(value)) return ExpressionNodeType.Unknown;

switch (value)
{
case "+":
return ExpressionNodeType.Plus;
case "-":
return ExpressionNodeType.Subtract;
case "*":
return ExpressionNodeType.MultiPly;
case "/":
return ExpressionNodeType.Divide;
case "%":
return ExpressionNodeType.Mod;
case "^":
return ExpressionNodeType.Power;
case "(":
return ExpressionNodeType.LParentheses;
case ")":
return ExpressionNodeType.RParentheses;
case "&":
return ExpressionNodeType.BitwiseAnd;
case "|":
return ExpressionNodeType.BitwiseOr;
case "&&":
return ExpressionNodeType.And;
case "||":
return ExpressionNodeType.Or;
case "!":
return ExpressionNodeType.Not;

case "==":
return ExpressionNodeType.Equal;
case "!=":
case "<>":
return ExpressionNodeType.Unequal;
case ">":
return ExpressionNodeType.GT;
case "<":
return ExpressionNodeType.LT;
case ">=":
return ExpressionNodeType.GTOrEqual;
case "<=":
return ExpressionNodeType.LTOrEqual;
case "<<":
return ExpressionNodeType.LShift;
case ">>":
return ExpressionNodeType.RShift;
default:
//判断是否操作数
if (IsNumerics(value))
{
return ExpressionNodeType.Numeric;
}
else
{
return ExpressionNodeType.Unknown;
}
}
}

///


/// 获取各节点类型的优先级
///

///
///
private static int GetNodeTypePRI(ExpressionNodeType nodeType)
{
switch (nodeType)
{
case ExpressionNodeType.LParentheses:
case ExpressionNodeType.RParentheses:
return 9;
//逻辑非是一元操作符,所以其优先级较高
case ExpressionNodeType.Not:
return 8;
case ExpressionNodeType.Mod:
return 7;
case ExpressionNodeType.MultiPly:
case ExpressionNodeType.Divide:
case ExpressionNodeType.Power:
return 6;
case ExpressionNodeType.Plus:
case ExpressionNodeType.Subtract:
return 5;
case ExpressionNodeType.LShift:
case ExpressionNodeType.RShift:
return 4;
case ExpressionNodeType.BitwiseAnd:
case ExpressionNodeType.BitwiseOr:
return 3;
case ExpressionNodeType.Equal:
case ExpressionNodeType.Unequal:
case ExpressionNodeType.GT:
case ExpressionNodeType.LT:
case ExpressionNodeType.GTOrEqual:
case ExpressionNodeType.LTOrEqual:
return 2;
case ExpressionNodeType.And:
case ExpressionNodeType.Or:
return 1;
default:
return 0;
}
}

///
/// 判断某个操作数是否是数值
///

///
///

turns>
public static bool IsNumerics(string op)
{
return Numerics.IsMatch(op);
}

///


/// 判断某个字符后是否需要更多的操作符
///

///
///
public static bool NeedMoreOperator(char c)
{
switch (c)
{
case '&':
case '|':
case '=':
case '!':
case '>':
case '<':
case '.': //小数点
return true;
}
//数字则需要更多
return char.IsDigit(c);
}

///
/// 判断两个字符是否是同一类
///

///
///
///
public static bool IsCongener(char c1, char c2)
{
if (c1 == '(' || c2 == '(') return false;
if (c1 == ')' || c2 == ')') return false;

if (char.IsDigit(c1) || c1 == '.')
{
//c1为数字,则c2也为数字
return (char.IsDigit(c2) || c2 == '.');
}
else
{
//c1为非数字,则c2也为非数字
return !(char.IsDigit(c2) || c2 == '.');
}
}

///
/// 判断某个字符是否是空白字符
///

///
///
public static bool IsWhileSpace(char c)
{
return c == ' ' || c == '\t';
}

///
/// 判断是否是一元操作符节点
///

///
///
public static bool IsUnitaryNode(ExpressionNodeType nodeType)
{
return (nodeType == ExpressionNodeType.Plus || nodeType == ExpressionNodeType.Subtract);
}

///
/// 操作数的正则表达式
///

private static Regex Numerics = new Regex(@"^[\+\-]?(0|[1-9]\d*|[1-9]\d*\.\d+|0\.\d+)$", https://www.360docs.net/doc/b66414528.html,piled);
#endregion
}
}
















using System;
using System.Collections.Generic;
using System.Text;

namespace CaculateExpression
{
///
/// 表达式节点的类型
///

public enum ExpressionNodeType
{
///
/// 未知
///

Unknown,
///
/// +
///

Plus,
///
/// -
///

Subtract,
///
/// *
///

MultiPly,
///

/// /
///


Divide,
///
/// (
///

LParentheses,
///
/// )
///

RParentheses,
///
/// % (求模,取余)
///

Mod,
///
/// ^ (次幂)
///

Power,
///
/// & (按位与)
///

BitwiseAnd,
///
/// | (按位或)
///

BitwiseOr,
///
/// && (逻辑与)
///

And,
///
/// || (逻辑或)
///

Or,
///
/// ! (逻辑非)
///

Not,
///
/// == (相等)
///

Equal,
///
/// != 或 <> (不等于)
///

Unequal,
///
/// > (大于)
///

GT,
///
/// < (小于)
///

LT,
///
/// >= (大于等于)
///

GTOrEqual,
///
/// <= (小于等于)
///

LTOrEqual,
///
/// << (左移位)
///

LShift,
///
/// >> (右移位)
///

RShift,
///
/// 数值
///

Numeric
}
}















using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace CaculateExpression
{
///
/// 表达式解析器
///

public class ExpressionParser
{
///
/// 构造表达式解析器
///

/// 要分析的表达式,如"1+2+3+4"
public ExpressionParser(string expression)
{
this._Expression = expression;
this._Position = 0;
}

///
/// 当前分析的表达式
///

private string _Expression;
///
/// 返回当前分析的表达式
///

public string Expression
{
get
{
return _Expression;
}
}
///
/// 当前读取的位置
///

private int _Position;
///
/// 返回当前读取的位置
///

public int Position
{
get
{
return _Position;
}

}

///


/// 读取下一个表达式节点,如果读取失败则返回null
///

///
public ExpressionNode ReadNode()
{
//空格的位置
int whileSpacePos = -1;

StringBuilder buffer = new StringBuilder(10);
while (this._Position < this._Expression.Length)
{
char c = this._Expression[this._Position];

//空白字符不处理
if (ExpressionNode.IsWhileSpace(c))
{
//判断两次的空白字符是否连续
if (whileSpacePos >=0 && (this._Position - whileSpacePos) > 1)
{
MessageBox.Show(string.Format("表达式\"{0}\"在位置({1})上的字符非法!", this._Expression, this._Position));
return null;
}
else
{
if (buffer.Length == 0)
{
//前空白不判断处理
whileSpacePos = -1;
}
else
{
whileSpacePos = this._Position;
}
this._Position++;
}
continue;
}

if (buffer.Length == 0 || ExpressionNode.IsCongener(c, buffer[buffer.Length - 1]))
{
//同一类字符则继续读取字符
this._Position++;
buffer.Append(c);
}
else
{
break;
}

//判断是否需要更多的操作符
if (!ExpressionNode.NeedMoreOperator(c)) break;
}

if (buffer.Length == 0) return null;

ExpressionNode expNode = new ExpressionNode(buffer.ToString());
if (expNode.Type == ExpressionNodeType.Unknown)
{
MessageBox.Show(string.Format("表达式\"{0}\"在位置({1})上的字符\"{2}\"非法!",
this._Expression, this._Position - expNode.Value.Length, expNode.Value));
return null;
}

return expNode;
}
}
}
































相关文档
最新文档