最近频繁解决计算方面的问题,其中就有实现字符串表达式计算返回结果值需求,通过使用栈实现,需要定义运算符号优先级,其它就不细说,代码如下: csStack.cs: using System; namespace PYHB { /// <summary> /// 栈堆设定。 /// 日期:2005-05-17 /// </summary> public class clsStack { private long Top; //栈最大序号 private int MaxSize; // MaxSize 栈的容量 private string[] Element; public clsStack() { // // TODO: 在此处添加构造函数逻辑 // Top=-1; } /// <summary> /// 设定栈大最大容量 /// </summary> /// <param name="Size"></param> public void Initialize(int Size) { MaxSize=Size; Element=new string[Size]; } /// <summary> /// 入栈 /// </summary> /// <param name="strItem"></param> public void Push(string strItem) { if(!IsFull()) { Top=Top+1; Element[Top] = strItem; } } /// <summary> /// 出栈 /// </summary> /// <returns></returns> public string Pop() { string strRtn=" "; if(!IsEmptly()) { strRtn = Element[Top]; Top=Top-1; } return strRtn; } public string GetTop() { string strRtn=" "; if(!IsEmptly()) { strRtn = Element[Top]; } return strRtn; } public bool IsFull() { bool IsFull=Top==(MaxSize-1)?true:false; return IsFull; } public void MakeEmptly() { Top = -1; } public bool IsEmptly() { bool IsEmptly=Top==-1?true:false; return IsEmptly; } } } calculate.cs using System; using System.Text; using System.Windows.Forms; namespace PYHB { /// <summary> /// 字符串表达式计算实现,返回计算结果字符数组 /// 日期:2005-05-17 /// </summary> public class Calculate { private clsStack S=new clsStack(); public Calculate() { // // TODO: 在此处添加构造函数逻辑 // } /// <summary> /// 根据数字表达式字符串数组,返回计算结果字符数组 /// </summary> /// <param name="strSoure">strSour 中缀表达式字符串,头部没有“#”,尾部需要加上“#”</param> /// <returns>计算结果</returns> public string[] Run(string[] strSoure) { if(strSoure==null) { return null; } string[] dRtn=new string[strSoure.Length]; for(int k=0;k<strSoure.Length;k++) { string[] ATemp; string strRPN; strRPN=GetRPN(strSoure[k]); try { ATemp=strRPN.Trim().Split(' '); for(int i=0;i<ATemp.Length;i++) { if(sysFun.IsNumber(ATemp[i])) S.Push(ATemp[i]); else DoOperate(ATemp[i]); } dRtn[k]=S.Pop(); } catch{} } return dRtn; } /// <summary> /// Run 返回后缀表达式 /// strSour 中缀表达式字符串,头部没有“#”,尾部需要加上“#” /// String 后缀表达式字符串,头尾都没有“#”
/// </summary> /// <param name="strSource"></param> /// <returns></returns> private string GetRPN(string strSource) { string[] ATemp; string strRPN="",Y; ATemp=strSource.Trim().Split(' '); S.Initialize(ATemp.Length); S.MakeEmptly(); S.Push("#"); try { for(int k=0;k<ATemp.Length;k++) { //数字 if(sysFun.IsNumber(ATemp[k])) { strRPN += " "+ATemp[k]; } //字符 else { if(ATemp[k]==")") { do { Y=S.Pop(); if(Y!="(") strRPN += " "+Y; } while(Y.Trim()!="("); } else { do { Y = S.Pop(); if (GetISP(Y) > GetICP(ATemp[k])) strRPN += " "+Y; } while(GetISP(Y) > GetICP(ATemp[k])); S.Push(Y); S.Push(ATemp[k]); } } } do { Y=S.Pop(); if(Y!="#") strRPN+=" "+Y; } while(Y!="#"); } catch{} return strRPN; } #region 运算符优先级定义 private enum isp { s35 = 0, s40 = 1, s94 = 7, s42 = 5, s47 = 5, s37 = 5, s43 = 3, s45 = 3, s41 = 8 } private enum icp { s35 = 0, s40 = 8, s94 = 6, s42 = 4, s47 = 4, s37 = 4, s43 = 2, s45 = 2, s41 = 1 } private int GetISP(string a1) { Encoding ascii =Encoding.ASCII; byte[] a=ascii.GetBytes(a1); switch(Convert.ToInt32(a[0])) { case 35: return (int)isp.s35; case 40: return (int)isp.s40; case 94: return (int)isp.s94; case 42: return (int)isp.s42; case 47: return (int)isp.s47; case 37: return (int)isp.s37; case 43: return (int)isp.s43; case 45: return (int)isp.s45; case 41: return (int)isp.s41; default: return (int)isp.s35; } } private int GetICP(string a1) { Encoding ascii =Encoding.ASCII; byte[] a=ascii.GetBytes(a1); switch(Convert.ToInt32(a[0])) { case 35: return (int)icp.s35; case 40: return (int)icp.s40; case 94: return (int)isp.s94; case 42: return (int)icp.s42; case 47: return (int)icp.s47; case 37: return (int)icp.s37; case 43: return (int)icp.s43; case 45: return (int)icp.s45; case 41: return (int)icp.s41; default: return (int)icp.s35; } } #endregion /// <summary> /// 判断是否存在左右数字,并且复制 /// </summary> /// <param name="dLeft">左数值</param> /// <param name="dRight">右的数值</param> /// <returns>是否成功</returns> private bool GetTwoItem(ref decimal dLeft,ref decimal dRight) { bool bRtn=true; try { if(S.IsEmptly()) return false; else dRight = Convert.ToDecimal(S.Pop()); if(S.IsEmptly()) return false; else dLeft = Convert.ToDecimal(S.Pop()); } catch { } return bRtn; } /// <summary> /// 根据运算符号计算,并且把计算结果以字符形式填充入栈 /// </summary> /// <param name="op"></param> private void DoOperate(string op) { decimal NumLeft=0,NumRight=0; bool r; r=GetTwoItem(ref NumLeft,ref NumRight); if(r) { switch(op.Trim()) { case "+": S.Push((NumLeft+NumRight).ToString()); break; case "-": S.Push((NumLeft-NumRight).ToString()); break; case "*": S.Push((NumLeft*NumRight).ToString()); break; case "/": if(NumRight==0) S.Push("0"); else S.Push((NumLeft/NumRight).ToString()); break; } } } } } 
|