using System;
using System.Collections;
namespace XXXXX
{
public class Expression
{
private Expression() {}
#region No01.表达式分割为ArrayList形式
///
/// 要求表达式以空格\t作为分隔符
/// 转换表达式折分为:
/// 变量及数值 ,变量不允许为@
/// 字符串“”
/// 运算符号{+、-、*、/、++、+=、--、-=、*=、/=、!、!=、>、>=、>>、<、<=、<>、|、|=、||、&、&=、&&}
/// 括号{包括(、)}
///
///
///
public static ArrayList ConvertExpression(string sExpression)
{
ArrayList alist = new ArrayList();
string word = null;
int i = 0;
string c = "";
while(i < sExpression.Length)
{
#region "
if (word != null && word != "")
if (word.Substring(0,1) == "\"")
{
do
{
c = sExpression[i++].ToString();
if (c == "\"") { alist.Add(word + c); word = c = null; break;}
else { word += c; c = null; }
}while(i < sExpression.Length);
}
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; break;}
#endregion
#region 字符判别
switch (c = sExpression[i++].ToString())
{
#region ( )
case "\"":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; break;}
else
{
word = c; c= null;
do
{ c = sExpression[i++].ToString();
if (c == "\"") { alist.Add(word + c); word = c = null; break;}
else { word += c; c = null; }
}while(i < sExpression.Length );
break;
}
case "(": alist.Add(word); alist.Add(c); word = c= null; break;
case ")": alist.Add(word); alist.Add(c); word = c= null; break;
case " ": alist.Add(word); word = c= null; break;
#endregion
#region + - * / %
case "+":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case "+": alist.Add(word); alist.Add("++"); word = c= null; break;
case "=": alist.Add(word); alist.Add("+="); word = c= null; break;
default : alist.Add(word); alist.Add("+"); word = c= null; i--; break;
}
break;
case "-":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case "-": alist.Add(word); alist.Add("--"); word = c= null; break;
case "=": alist.Add(word); alist.Add("-="); word = c= null; break;
default : alist.Add(word); alist.Add("-"); word = c= null;i--; break;
}
break;
case "*":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case "=": alist.Add(word); alist.Add("*="); word = c= null; break;
default : alist.Add(word); alist.Add("*"); word = c= null; i--; break;
}
break;
case "/":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case "=": alist.Add(word); alist.Add("/="); word = c= null; break;
default : alist.Add(word); alist.Add("/"); word = c= null;i--; break;
}
break;
case "%":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case "=": alist.Add(word); alist.Add("%="); word = c= null; break;
default : alist.Add(word); alist.Add("%"); word = c= null; i--; break;
}
break;
#endregion
#region > < =
case ">":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case ">": alist.Add(word); alist.Add(">>"); word = c= null; break;
case "=": alist.Add(word); alist.Add(">="); word = c= null; break;
default : alist.Add(word); alist.Add(">"); word =c= null;i--; break;
}
break;
case "<":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case "<": alist.Add(word); alist.Add("<<"); word = c= null; break;
case ">": alist.Add(word); alist.Add("<>"); word = c= null; break;
case "=": alist.Add(word); alist.Add("<="); word = c= null; break;
default : alist.Add(word); alist.Add("<"); word = c =null;i--; break;
}
break;
case "=":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case "=": alist.Add(word); alist.Add("=="); word = c= null; break;
default : alist.Add(word); alist.Add("="); word = c=null;i--; break;
}
break;
#endregion
#region ! | &
case "!":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case "=": alist.Add(word); alist.Add("!="); word = c= null; break;
default : alist.Add(word); alist.Add("!"); word = c=null;i--; break;
}
break;
case "|":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case "=": alist.Add(word); alist.Add("|="); word = c= null; break;
case "|": alist.Add(word); alist.Add("||"); word = c= null; break;
default : alist.Add(word); alist.Add("|"); word =c= null;i--; break;
}
break;
case "&":
if (i > sExpression.Length -1)
{ alist.Add(word); alist.Add(c); word = c= null; }
else
switch (c = sExpression[i++].ToString())
{
case "=": alist.Add(word); alist.Add("&="); word = c= null; break;
case "&": alist.Add(word); alist.Add("&&"); word = c= null; break;
default : alist.Add(word); alist.Add("&"); word =c= null;i--; break;
}
break;
#endregion
default:
word += c;
break;
}
if (i == sExpression.Length) alist.Add(word);
#endregion
}
ArrayList alresult = new ArrayList();
foreach (object a in alist)
{
if (a == null) continue ;
if (a.ToString().Trim() == "") continue ;
alresult.Add(a);
}
return alresult;
}
///
/// 对返回的表达式,已经分好放于ArrayList中的变量进行替换为实际常量
///
///
///
///
///
public static ArrayList ConvertExpression(ArrayList alExpression, string mapVar, string mapValue)
{
for (int i = 0; i < alExpression.Count; i++)
{
if (alExpression[i].ToString() == mapVar ) { alExpression[i] = mapValue; break; }
}
return alExpression;
}
///
/// 对返回的表达式,已经分好放于ArrayList中的变量进行替换为实际常量
///
///
///
///
///
public static ArrayList ConvertExpression(ArrayList alExpression, string[] mapVar, string[] mapValue)
{
for (int i = 0; i < alExpression.Count; i++)
{
for (int j = 0; j< mapVar.Length; j++)
{
if (alExpression[i].ToString() == mapVar[j] )
{
alExpression[i] = mapValue[j];
break;
}
// System.Console.WriteLine("Expression: {0} >>> {1}",mapVar[j], mapValue[j]);
}
}
return alExpression;
}
#endregion
#region No02.后缀表达式方式 解析表达式
///
/// 找出第一个闭括号
///
///
///
public static int Find_First_RightBracket(ArrayList alExpression)
{
for (int i = 0; i < alExpression.Count; i++)
{if (OperatorMap.CheckRightBracket(alExpression[i].ToString())) return i; }
return 0;
}
///
/// 找出匹配的开括号
///
///
///
///
public static int Find_Near_LeftBracket(ArrayList alExpression, int iRightBracket)
{
int i = iRightBracket - 2;
while ( i>= 0 )
{
if (OperatorMap.CheckLeftBracket(alExpression[i].ToString())) return i;
i--;
}
return 0;
}
///
/// 中缀表达式转换为后缀表达式
///
///
///
public static ArrayList ConvertToPostfix(ArrayList alexpression)
{
ArrayList alOutput = new ArrayList();
Stack sOperator = new Stack();
string word = null;
int count = alexpression.Count;
int i = 0;
while (i < count)
{
word = alexpression[i++].ToString();
//·读到左括号时总是将它压入栈中
if (OperatorMap.CheckLeftBracket(word))
{ sOperator.Push(word); }
else
//·读到右括号时,将*近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号。
if (OperatorMap.CheckRightBracket(word))
{
while (true)
{
if (sOperator.Count == 0) break;
string sTop = sOperator.Peek().ToString();
if (sTop == "(" ) { sOperator.Pop(); break;}
else alOutput.Add(sOperator.Pop());
}
}
else
//·当读到数字直接送至输出队列中
if (OperatorMap.IsVar(word))
{ alOutput.Add(word); }
else
//·当读到运算符t时,
// a.将栈中所有优先级高于或等于t的运算符弹出,送到输出队列中;
// b.t进栈
if (OperatorMap.CheckOperator(word))
{
while(sOperator.Count > 0)
{
string sPop = sOperator.Peek().ToString();
if (sPop =="(" ) break;
if (OperatorMap.GetMaxprior(word,sPop) >= 0)
{
// sPop = sOperator.Pop().ToString();
alOutput.Add(sOperator.Pop().ToString());
}
else
break;
// System.Console.WriteLine("XH{0}",sPop);
}
sOperator.Push(word);
}
// System.Console.WriteLine("{0}",word.ToString());
}
//中缀表达式全部读完后,若栈中仍有运算符,将其送到输出队列中
while (sOperator.Count > 0)
{
string s = sOperator.Pop().ToString();
alOutput.Add(s);
// System.Console.WriteLine("{0}:{1}",sOperator.Count,s.ToString());
}
return alOutput;
}
///
/// 计算后缀表达式
///
///
///
public static object ComputePostfix(ArrayList alexpression)
{
try
{
//·建立一个栈S
Stack s = new Stack();
int count = alexpression.Count;
int i = 0;
while (i < count)
{
//·从左到右读后缀表达式,读到数字就将它转换为数值压入栈S中,
string word = alexpression[i++].ToString();
if (OperatorMap.IsVar(word))
{
s.Push(word);
// System.Console.WriteLine("Push:{0}",word);
}
else//读到运算符则从栈中依次弹出两个数分别到Y和X,
if (OperatorMap.CheckOperator(word))
{
string y,x,sResult;
if (!CheckOneOperator(word))
{
y = s.Pop().ToString();
x = s.Pop().ToString();
//然后以“X 运算符 Y”的形式计算机出结果,再压加栈S中
sResult = ComputeTwo(x,y,word).ToString();
s.Push(sResult);
}
else
{
x = s.Pop().ToString();
sResult = ComputeOne(x, word).ToString();
s.Push(sResult);
}
}
}
string spop = s.Pop().ToString();
// System.Console.WriteLine("Result:{0}",spop);
return spop;
}
catch
{
System.Console.WriteLine("Result:表达式不符合运算规则!Sorry!");
return "Sorry!Error!";
}
}
public static object ComputeExpression(string sExpression)
{
return Expression.ComputePostfix(Expression.ConvertToPostfix(Expression.ConvertExpression(sExpression)));
}
public static object ComputeExpression(string sExpression, string mapVar, string mapValue)
{
return Expression.ComputePostfix(Expression.ConvertToPostfix(Expression.ConvertExpression(Expression.ConvertExpression(sExpression),mapVar,mapValue)));
}
public static object ComputeExpression(string sExpression, string[] mapVar, string[] mapValue)
{
return Expression.ComputePostfix(Expression.ConvertToPostfix(Expression.ConvertExpression(Expression.ConvertExpression(sExpression),mapVar,mapValue)));
}
#endregion
#region No03. 简单无括号表达式的计算
#region 检查字符可以转换的类型
public static bool CheckNumber(string str)
{
try { Convert.ToDouble(str); return true; }
catch{return false;}
}
public static bool CheckBoolean(string str)
{
try { Convert.ToBoolean(str); return true; }
catch{return false;}
}
public static bool CheckString(string str)
{
try
{
str = str.Replace("\"","");
char c = (char)(str[0]);
if ((c >= 'a') && (c <= 'z') || (c >= 'A') && (c <= 'Z'))
return true;
else
return false;
}
catch{ return false;}
}
public static bool CheckOneOperator(string sOperator)
{
if (sOperator == "++" || sOperator =="--" || sOperator == "!")
return true;
else
return false;
}
#endregion
#region 双目运算
public static object ComputeTwoNumber(double dL, double dR, string sO)
{
switch (sO)
{
case "+": return (dL + dR);
case "-": return (dL - dR);
case "*": return (dL * dR);
case "%": return (dL % dR);
case "/": try{return (dL / dR);}
catch
{
return false;
//return "ComputeTwoNumber ["+sO+"] Sorry!";
}
case "+=": return (dL += dR);
case "-=": return (dL -= dR);
case "*=": return (dL *= dR);
case "/=": try{return (dL /= dR);}
catch
{
return false;
//return "ComputeTwoNumber ["+sO+"] Sorry!";
}
case "=": return (dL == dR);
case "==": return (dL == dR);
case "!=": return (dL != dR);
case "<>": return (dL != dR);
case ">": return (dL.CompareTo(dR) > 0);
case ">=": return (dL.CompareTo(dR) >= 0);
case "<": return (dL.CompareTo(dR) < 0);
case "<=": return (dL.CompareTo(dR) <= 0);
case ">>": return (int)dL >> (int)dR;
case "<<": return (int)dL << (int)dR;
case "|": return (int)dL | (int)dR;
case "&": return (int)dL & (int)dR;
case "|=":
{
int iL = (int)dL;
int iR = (int)dR;
return iL |= iR;
}
case "&=":
{
int iL = (int)dL;
int iR = (int)dR;
return iL &= iR;
}
default :
return false;
//return "ComputeTwoNumber ["+sO+"] Sorry!";
}
}
public static object ComputeTwoBoolean(bool bL, bool bR , string sO)
{
switch (sO)
{
case ">": return bL.CompareTo(bR) > 0 ;
case ">=": return bL.CompareTo(bR) >= 0 ;
case "<": return bL.CompareTo(bR) < 0 ;
case "<=": return bL.CompareTo(bR) <= 0 ;
case "=": return bL == bR ;
case "==": return bL == bR ;
case "!=": return bL != bR ;
case "<>": return bL != bR ;
case "||": return bL || bR ;
case "&&": return bL && bR ;
default : return false;
//return "ComputeTwoBoolean ["+sO+"] Sorry!";
}
}
public static object ComputeTwoString(string sL, string sR, string sO)
{
switch (sO)
{
case "+": return sL + sR;
case "=": return (sL == sR);
case "==": return (sL == sR);
case "!=": return (sL != sR);
case "<>": return (sL != sR);
case ">": return (sL.CompareTo(sR) > 0);
case ">=": return (sL.CompareTo(sR) >= 0);
case "<": return (sL.CompareTo(sR) < 0);
case "<=": return (sL.CompareTo(sR) <= 0);
default : return false;
//return "ComputeTwoString ["+sO+"] Sorry!";
}
}
public static object ComputeTwo(string sL, string sR, string sO)
{
if (CheckNumber(sL))
{
if (CheckNumber(sR))
return ComputeTwoNumber(Convert.ToDouble(sL),Convert.ToDouble(sR),sO);
else
if (CheckString(sR)) return ComputeTwoString(sL,sR,sO);
}
else if (CheckBoolean(sL))
{
if (CheckBoolean(sR))
return ComputeTwoBoolean(Convert.ToBoolean(sL),Convert.ToBoolean(sR),sO);
else
if (CheckString(sR)) return ComputeTwoString(sL,sR,sO);
}
else if (CheckString(sL)) return ComputeTwoString(sL,sR,sO);
return "ComputeTwo ["+sL+"]["+sO+"]["+sR+"] Sorry!";
}
#endregion
#region 单目运算
public static object ComputeOneNumber(double dou, string sO)
{
switch (sO)
{
case "++": return (dou + 1);
case "--": return (dou - 1);
default : return false;
//return "ComputeOneNumber ["+sO+"] Sorry!";
}
}
public static object ComputeOneString(string str, string sO)
{
switch (sO)
{
case "++": return (str + str);
default : return false;
//return "ComputeOneString ["+sO+"] Sorry!";
}
}
public static object ComputeOneBoolean(bool bo, string sO)
{
switch (sO)
{
case "!": return (!bo);
default : return false;
// return "ComputeOneBoolean ["+sO+"] Sorry!";
}
}
public static object ComputeOne(string str, string sO)
{
if (CheckNumber(str))
return ComputeOneNumber(Convert.ToDouble(str),sO);
if (CheckBoolean(str))
return ComputeOneBoolean(Convert.ToBoolean(str),sO);
if (CheckString(str))
return ComputeOneString(str,sO);
return "ComputerOne ["+str+"]["+sO+"] Sorry!";
}
#endregion
#endregion
#region No04. 实用工具类
///
/// ArrayList子集操作
///
public class ArrayListCopy
{
private ArrayListCopy(){}
///
/// 返回ArrayList子集{L--R}内容
///
///
///
///
///
public static ArrayList CopyBewteenTo(ArrayList alist, int iLeft, int iRight)
{
ArrayList alResult = new ArrayList();
bool b = false;
for (int i = iLeft; i < iRight; i++)
{
alResult.Add(alist[i]);
b = true;
}
if (b) return alResult;
else return null;
}
///
/// 返回ArrayList子集{L--R}的补集内容
///
///
///
///
///
public static ArrayList CopyNotBetweenTo(ArrayList alist, int iLeft, int iRight)
{
ArrayList alResult = new ArrayList();
bool b = false;
for (int i = 0; i < iLeft - 1; i++)
{
alResult.Add(alist[i]);
b = true;
}
if (b)
{
alResult.Add("@");
for (int i = iRight + 1; i < alist.Count; i++)
{
alResult.Add(alist[i]);
b = true;
}
}
if (b) return alResult;
else return null;
}
///
/// 统计字符串sin在str中出现的次数
///
///
///
///
public static int GetSubStringCount(string str, string sin)
{
int i = 0;
int ibit = 0;
while (true)
{
ibit = str.IndexOf(sin, ibit);
if (ibit > 0 )
{
ibit += sin.Length;
i++;
}
else
{
break;
}
}
return i;
}
}
///
/// 算符的优先级实体
///
public class OperatorMap
{
public struct Map
{
public int Priority;
public string Operator;
public Map(int iPrior, string sOperator)
{
Priority = iPrior;
Operator = sOperator;
}
}
private OperatorMap(){ }
public static Map[] map()
{
Map[] om;
om = new Map[30];
om[0] = new Map(5,"*");
om[1] = new Map(5,"/");
om[29] = new Map(5,"%");
om[2] = new Map(10,"+");
om[3] = new Map(10,"-");
om[4] = new Map(20, ">");
om[5] = new Map(20, ">=");
om[6] = new Map(20, "<");
om[7] = new Map(20, "<=");
om[8] = new Map(20, "<>");
om[9] = new Map(20, "!=");
om[10] = new Map(20, "==");
om[11] = new Map(20, "=");
om[12] = new Map(41, "!");
om[13] = new Map(42, "||");
om[14] = new Map(43, "&&");
om[15] = new Map(40, "++");
om[16] = new Map(40, "--");
om[17] = new Map(40, "+=");
om[18] = new Map(40, "-=");
om[19] = new Map(40, "*=");
om[20] = new Map(40, "/=");
om[21] = new Map(40, "&");
om[22] = new Map(40, "|");
om[23] = new Map(40, "&=");
om[24] = new Map(40, "|=");
om[25] = new Map(40, ">>");
om[26] = new Map(40, "<<");
om[27] = new Map(3,"(");
om[28] = new Map(3,")");
return om;
}
public static bool CheckLeftBracket(string str) { return ( str== "(");}
public static bool CheckRightBracket(string str){ return ( str== ")");}
public static bool CheckBracket(string str) { return ( str== "(" || str == ")"); }
public static bool CheckOperator(string scheck)
{
string[] Operator= {"+", "-", "*", "/", "%",
">", ">=", "<", "<=", "<>", "!=", "==", "=",
"!", "||", "&&",
"++", "--", "+=", "-=", "*=", "/=",
"&", "|", "&=", "|=",
">>", "<<",
")", "("
};
bool bl = false;
for (int i = 0; i < Operator.Length - 1; i++ ) { if (Operator[i] == scheck){bl = true; break;} }
return bl;
}
public static Map GetMap(string Operator)
{
if (CheckOperator(Operator)) foreach(Map tmp in map()){ if (tmp.Operator == Operator) return tmp; }
return new Map(99,Operator);
}
public static int Getprior(string Operator) { return GetMap(Operator).Priority; }
public static int GetMaxprior(string Loperator, string Roperator)
{return GetMap(Loperator).Priority - GetMap(Roperator).Priority;}
public static bool IsVar(string svar)
{
if ((svar[0] >= '0' && svar[0] <= '9' ) || (svar[0] >= 'a' && svar[0] <= 'z') || (svar[0] >='A' && svar[0] <='Z') )
return true;
else
return false;
}
}
#endregion
}
}