栈实现字符串表达式计算

最近频繁解决计算方面的问题,其中就有实现字符串表达式计算返回结果值需求,通过使用栈实现,需要定义运算符号优先级,其它就不细说,代码如下:  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))
      S.Push(ATemp);
      else
      DoOperate(ATemp);
    }
 
    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;      }
  }
  }  }  }

 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。
 您可能对 [Asp.Net] 的这些文章也感兴趣:

ASP.NET2.0,无刷新页面新境界!
创建ASP.NET监视服务器进程
ASP.NET 14个基础问题
ASP.NET状态保存方法
只让输入数字的输入框(javascript)
.net 2.0 rest 实现
Friendly GridView Deletion Messages
ASP.NET2.0 SQL Server2005构建多层应用(1)
ASP.NET木马及Webshell安全解决方案
ASP.NET 3.5 Extensions CTP-ASP.NET MVC框架和Silverlight支持