科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件用Visual C# 实现四则混合运算

用Visual C# 实现四则混合运算

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

文本描述了四则混合运算的常用解决方法,详细描述了使用栈的方式解决四则混合运算,并给出了C#实现代码。

作者:顾君彦 来源:天极网 2007年11月13日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
程序实现

  本文,给出使用栈处理四则运算的C#实现方法,如下:

CalUtility.cs

using System;
namespace Calculate
{
 /// <summary>
 /// CalUtility 的摘要说明。
 /// 读算式辅助工具
 /// </summary>

 public class CalUtility
 {
  System.Text.StringBuilder StrB;
  private int iCurr=0;
  private int iCount=0;

  /// <summary>
  /// 构造方法
  /// </summary>

  public CalUtility(string calStr)
  {
   StrB = new System.Text.StringBuilder(calStr.Trim());
   iCount = System.Text.Encoding.Default.GetByteCount(calStr.Trim());
  }

  /// <summary>
  /// 取段,自动分析数值或计算符
  /// </summary>
  /// <returns></returns>

  public string getItem()
  {
   //结束了
   if(iCurr==iCount)
    return "";
   char ChTmp = StrB[iCurr];
   bool b=IsNum(ChTmp);
   if(!b)
   {
    iCurr++;
    return ChTmp.ToString();
   }
   string strTmp="";
   while(IsNum(ChTmp)==b && iCurr<iCount)
   {
    ChTmp = StrB[iCurr];
    if(IsNum(ChTmp)==b)
     strTmp +=ChTmp;
    else
     break;
    iCurr++;
   }
   return strTmp;
  }

  /// <summary>
  /// 是否是数字
  /// </summary>
  /// <param name="c">内容</param>
  /// <returns></returns>

  public bool IsNum(char c)
  {
   if((c>=’0’ && c<=’9’)|| c==’.’)
   {
    return true;
   }
   else
   {
    return false;
   }
  }

  /// <summary>
  /// 是否是数字
  /// </summary>
  /// <param name="c">内容</param>
  /// <returns></returns>

  public bool IsNum(string c)
  {
   if(c.Equals(""))
    return false;
   if((c[0]>=’0’ && c[0]<=’9’)|| c[0]==’.’)
   {
    return true;
   }
   else
   {
    return false;
   }
  }

  /// <summary>
  /// 比较str1和str2两个运算符的优先级,ture表示str1高于str2,false表示str1低于str2
  /// </summary>
  /// <param name="str1">计算符1</param>
  /// <param name="str2">计算符2</param>
  /// <returns></returns>

  public bool Compare(string str1,string str2)
  {
   return getPriority(str1)>=getPriority(str2);
  }

  /// <summary>
  /// 取得计算符号的优先级
  /// </summary>
  /// <param name="str">计算符</param>
  /// <returns></returns>

  public int getPriority(string str)
  {
   if(str.Equals(""))
   {
    return -1;
   }
   if(str.Equals("("))
   {
    return 0;
   }
   if(str.Equals("+")||str.Equals("-"))
   {
    return 1;
   }
   if(str.Equals("*")||str.Equals("/"))
   {
    return 2;
   }
   if(str.Equals(")"))
   {
    return 0;
   }
   return 0;
  }
 }
}

IOper.cs
using System;

namespace Calculate
{
 /// <summary>
 /// IOper 的摘要说明。
 /// 计算符接口
 /// </summary>

 public interface IOper
 {
  /// <summary>
  /// 计算符计算接口计算方法
  /// </summary>
  /// <param name="o1">参数1</param>
  /// <param name="o2">参数2</param>
  /// <returns></returns>
  object Oper(object o1,object o2);
 }
}

Opers.cs
using System;

namespace Calculate
{
 /// <summary>
 /// Opers 的摘要说明。
 /// 各类计算符的接口实现,加减乘除
 /// </summary>

 public class OperAdd:IOper
 {
  public OperAdd()
  {
   //
   // TODO: 在此处添加构造函数逻辑
   //
  }
  #region IOper 成员

 public object Oper(object o1, object o2)
 {
  Decimal d1 = Decimal.Parse(o1.ToString());
  Decimal d2 = Decimal.Parse(o2.ToString());
  return d1+d2;
 }

 #endregion
}

public class OperDec:IOper
{
 public OperDec()
 {
  //
  // TODO: 在此处添加构造函数逻辑
  //
 }
 #region IOper 成员

 public object Oper(object o1, object o2)
 {
  Decimal d1 = Decimal.Parse(o1.ToString());
  Decimal d2 = Decimal.Parse(o2.ToString());
  return d1-d2;
 }
 #endregion
}

public class OperRide:IOper
{
 public OperRide()
 {
  //
  // TODO: 在此处添加构造函数逻辑
  //
 }
 #region IOper 成员

 public object Oper(object o1, object o2)
 {
  Decimal d1 = Decimal.Parse(o1.ToString());
  Decimal d2 = Decimal.Parse(o2.ToString());
  return d1*d2;
 }
 #endregion
}

public class OperDiv:IOper
{
 public OperDiv()
 {
  //
  // TODO: 在此处添加构造函数逻辑
  //
 }
 #region IOper 成员

 public object Oper(object o1, object o2)
 {
  Decimal d1 = Decimal.Parse(o1.ToString());
  Decimal d2 = Decimal.Parse(o2.ToString());
  return d1/d2;
 }

 #endregion
}

}

OperFactory.cs
using System;

namespace Calculate
{
 /// <summary>
 /// OperFactory 的摘要说明。
 /// 计算符接口工厂
 /// </summary>
 public class OperFactory
 {
  public OperFactory()
  {
  }
  public IOper CreateOper(string Oper)
  {
   if(Oper.Equals("+"))
   {
    IOper p = new OperAdd();
    return p;
   }
   if(Oper.Equals("-"))
   {
    IOper p = new OperDec();
    return p;
   }
   if(Oper.Equals("*"))
   {
    IOper p = new OperRide();
    return p;
   }
   if(Oper.Equals("/"))
   {
    IOper p = new OperDiv();
    return p;
   }
   return null;
  }
 }
}

Calculate.cs
using System;
using System.Collections;

namespace Calculate
{
 /// <summary>
 /// Calculate 的摘要说明。
 /// 计算实现主类
 /// </summary>
 public class Calculate
 {
  /// <summary>
  /// 算术符栈
  /// </summary>
  private ArrayList HList;
  /// <summary>
  /// 数值栈
  /// </summary>
  public ArrayList Vlist;
  /// <summary>
  /// 读算试工具
  /// </summary>
  private CalUtility cu;
  /// <summary>
  /// 运算操作器工厂
  /// </summary>
  private OperFactory of;
  /// <summary>
  /// 构造方法
  /// </summary>
  /// <param name="str">算式</param>
  public Calculate(string str)
  {
   //
   // TODO: 在此处添加构造函数逻辑
   //
   HList = new ArrayList();
   Vlist = new ArrayList();
   of = new OperFactory();
   cu = new CalUtility(str);
  }

  /// <summary>
  /// 开始计算
  /// </summary>

  public object DoCal()
  {
   string strTmp=cu.getItem();
   while(true)
   {
    if(cu.IsNum(strTmp))
    {
     //如果是数值,则写入数据栈
     Vlist.Add(strTmp);
    }
    else
    {
     //数值
     Cal(strTmp);
    }
    if(strTmp.Equals(""))
     break;
    strTmp=cu.getItem();
   }
   return Vlist[0];
  }

  /// <summary>
  /// 计算
  /// </summary>
  /// <param name="str">计算符</param>

  private void Cal(string str)
  {
   //符号表为空,而且当前符号为"",则认为已经计算完毕
   if(str.Equals("")&&HList.Count==0)
    return;
   if(HList.Count>0)
   {
    //符号是否可以对消?
    if(HList[HList.Count-1].ToString().Equals("(") && str.Equals(")"))
    {
     HList.RemoveAt(HList.Count-1);
     if(HList.Count>0)
     {
      str=HList[HList.Count-1].ToString();
      HList.RemoveAt(HList.Count-1);
      Cal(str);
     }
     return;
    }
    //比较优先级
    if(cu.Compare(HList[HList.Count-1].ToString(),str))
    {
     //如果优先,则计算
     IOper p = of.CreateOper(HList[HList.Count -1].ToString());
     if(p!=null)
     {
      Vlist[Vlist.Count -2] = p.Oper(Vlist[Vlist.Count-2],Vlist[Vlist.Count-1]);
      HList.RemoveAt(HList.Count -1);
      Vlist.RemoveAt(Vlist.Count -1);
      Cal(str);
     }
     return;
    }
    if(!str.Equals(""))
     HList.Add(str);
   }
   else
   {
    if(!str.Equals(""))
     HList.Add(str);
   }
  }
 }
}

  后记

  使用这种方法,我们可以完成更复杂的混合运算,比如说:可以支持函数运算的混合运算,更进一步,可以支持自定义函数的混合运算,最终可以将这种算法运用在自定义报表、工资处理等等应用领域,很希望有相关兴趣的朋友与我交流。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章