public class ExpressionParse { private ExpressionParse() { } #region No01.表达式分割为ArrayList形式 /// <summary> /// 要求表达式以空格\t作为分隔符 /// 转换表达式折分为: /// 变量及数值 ,变量不允许为@ /// 字符串“” /// 运算符号{+、-、*、/、++、+=、--、-=、*=、/=、!、!=、>、>=、>>、<、<=、<>、|、|=、||、&、&=、&&} /// 括号{包括(、)} /// </summary> /// <param name="sExpressionParse"></param> /// <returns></returns> public static ArrayList ConvertExpressionParse(string sExpressionParse) { ArrayList alist = new ArrayList(); string word = null; int i = 0; string c = ""; while (i < sExpressionParse.Length) { #region " if (word != null && word != "") if (word.Substring(0, 1) == "\"") { do { c = sExpressionParse[i++].ToString(); if (c == "\"") { alist.Add(word + c); word = c = null; break; } else { word += c; c = null; } } while (i < sExpressionParse.Length); } if (i > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; break; } #endregion #region 字符判别 switch (c = sExpressionParse[i++].ToString()) { #region ( ) case "\"": if (i > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; break; } else { word = c; c = null; do { c = sExpressionParse[i++].ToString(); if (c == "\"") { alist.Add(word + c); word = c = null; break; } else { word += c; c = null; } } while (i < sExpressionParse.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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 > sExpressionParse.Length - 1) { alist.Add(word); alist.Add(c); word = c = null; } else switch (c = sExpressionParse[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 == sExpressionParse.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; } /// <summary> /// 对返回的表达式,已经分好放于ArrayList中的变量进行替换为实际常量 /// </summary> /// <param name="alExpressionParse"></param> /// <param name="mapVar"></param> /// <param name="mapValue"></param> /// <returns></returns> public static ArrayList ConvertExpressionParse(ArrayList alExpressionParse, string mapVar, string mapValue) { for (int i = 0; i < alExpressionParse.Count; i++) { if (alExpressionParse[i].ToString() == mapVar) { alExpressionParse[i] = mapValue; break; } } return alExpressionParse; } /// <summary> /// 对返回的表达式,已经分好放于ArrayList中的变量进行替换为实际常量 /// </summary> /// <param name="alExpressionParse"></param> /// <param name="name"></param> /// <param name="mapvalue"></param> /// <returns></returns> public static ArrayList ConvertExpressionParse(ArrayList alExpressionParse, string[] mapVar, string[] mapValue) { for (int i = 0; i < alExpressionParse.Count; i++) { for (int j = 0; j < mapVar.Length; j++) { if (alExpressionParse[i].ToString() == mapVar[j]) { alExpressionParse[i] = mapValue[j]; break; } // System.Console.WriteLine("ExpressionParse: {0} >>> {1}",mapVar[j], mapValue[j]); } } return alExpressionParse; } #endregion #region No02.后缀表达式方式 解析表达式 /// <summary> /// 找出第一个闭括号 /// </summary> /// <param name="alExpressionParse"></param> /// <returns></returns> public static int Find_First_RightBracket(ArrayList alExpressionParse) { for (int i = 0; i < alExpressionParse.Count; i++) { if (OperatorMap.CheckRightBracket(alExpressionParse[i].ToString())) return i; } return 0; } /// <summary> /// 找出匹配的开括号 /// </summary> /// <param name="alExpressionParse"></param> /// <param name="iRightBracket"></param> /// <returns></returns> public static int Find_Near_LeftBracket(ArrayList alExpressionParse, int iRightBracket) { int i = iRightBracket - 2; while (i >= 0) { if (OperatorMap.CheckLeftBracket(alExpressionParse[i].ToString())) return i; i--; } return 0; } /// <summary> /// 中缀表达式转换为后缀表达式 /// </summary> /// <param name="alExpressionParse"></param> /// <returns></returns> public static ArrayList ConvertToPostfix(ArrayList alExpressionParse) { ArrayList alOutput = new ArrayList(); Stack sOperator = new Stack(); string word = null; int count = alExpressionParse.Count; int i = 0; while (i < count) { word = alExpressionParse[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; } /// <summary> /// 计算后缀表达式 /// </summary> /// <param name="alExpressionParse"></param> /// <returns></returns> public static object ComputePostfix(ArrayList alExpressionParse) { try { //·建立一个栈S Stack s = new Stack(); int count = alExpressionParse.Count; int i = 0; while (i < count) { //·从左到右读后缀表达式,读到数字就将它转换为数值压入栈S中, string word = alExpressionParse[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 ComputeExpressionParse(string sExpressionParse) { return ExpressionParse.ComputePostfix(ExpressionParse.ConvertToPostfix(ExpressionParse.ConvertExpressionParse(sExpressionParse))); } public static object ComputeExpressionParse(string sExpressionParse, string mapVar, string mapValue) { return ExpressionParse.ComputePostfix(ExpressionParse.ConvertToPostfix(ExpressionParse.ConvertExpressionParse(ExpressionParse.ConvertExpressionParse(sExpressionParse), mapVar, mapValue))); } public static object ComputeExpressionParse(string sExpressionParse, string[] mapVar, string[] mapValue) { return ExpressionParse.ComputePostfix(ExpressionParse.ConvertToPostfix(ExpressionParse.ConvertExpressionParse(ExpressionParse.ConvertExpressionParse(sExpressionParse), 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. 实用工具类 /// <summary> /// ArrayList子集操作 /// </summary> public class ArrayListCopy { private ArrayListCopy() { } /// <summary> /// 返回ArrayList子集{L--R}内容 /// </summary> /// <param name="alist"></param> /// <param name="iLeft"></param> /// <param name="iRight"></param> /// <returns></returns> 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; } /// <summary> /// 返回ArrayList子集{L--R}的补集内容 /// </summary> /// <param name="alist"></param> /// <param name="iLeft"></param> /// <param name="iRight"></param> /// <returns></returns> 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; } /// <summary> /// 统计字符串sin在str中出现的次数 /// </summary> /// <param name="str"></param> /// <param name="sin"></param> /// <returns></returns> 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; } } /// <summary> /// 算符的优先级实体 /// </summary> 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 }
如果您也喜欢它,动动您的小指点个赞吧