【挑战你的技术,有格就来试试】 !!!

lizhigang770 2009-11-05 06:25:47
用C#做一个数学公式分析程序。

具有以下几种运输符号。
“+”,“-”,“*”,“/”,“%”,“^(幂)”,“abs()”,“sin”,“cos”,“sqr”,“tan”,“log”
例题如:
9+8-7*6/5%4^3+ABS( -25)+SIN( 25)+COS( 25)+SQR( 25)+TAN(25 )+LOG( 25)

最终要求。输入任意包括以上运算符的程式然后求解。

参考例题。只添加了+ ,-,*,/ 未添加完整。

http://soft.yesky.com/194/2054194_1.shtml


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);
   }
  }
 }
}

...全文
210 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
OROCHIORI35 2009-11-12
  • 打赏
  • 举报
回复
大家回答问题不是为了分多分少 但好歹也给点分意思下啊
lizhigang770 2009-11-12
  • 打赏
  • 举报
回复
高手跑哪儿去了
vssvss 2009-11-12
  • 打赏
  • 举报
回复
学习中啊 都是高手们的游戏 我是观望的
wartim 2009-11-09
  • 打赏
  • 举报
回复
这就是0分和200分的区别
lizhigang770 2009-11-09
  • 打赏
  • 举报
回复
看来真的有点难
xiaogug01 2009-11-07
  • 打赏
  • 举报
回复
帮 顶
benbenRH 2009-11-07
  • 打赏
  • 举报
回复
看数据结构的书,里面有讲。用堆栈来实现就可以了
lizhigang770 2009-11-07
  • 打赏
  • 举报
回复
我只判断了 + ,—,*,/。其余的我也不知道怎么弄了
[Quote=引用 10 楼 wzp144650 的回复:]
上周工作中做了一个跟这个类似的东西,但是不是计算,而是判断所输入的公式是否合法

你这个如何判断公式是否符合数学表达式的?我好像没有看到呀。

比如有人输入一个ABS(()怎么办?
[/Quote]
wzp144650 2009-11-07
  • 打赏
  • 举报
回复
上周工作中做了一个跟这个类似的东西,但是不是计算,而是判断所输入的公式是否合法

你这个如何判断公式是否符合数学表达式的?我好像没有看到呀。

比如有人输入一个ABS(()怎么办?
lizhigang770 2009-11-07
  • 打赏
  • 举报
回复
有高手吗,拜托解答一下
liherun 2009-11-07
  • 打赏
  • 举报
回复
无聊
michaelnami 2009-11-07
  • 打赏
  • 举报
回复
没看完 太长了
lizhigang770 2009-11-07
  • 打赏
  • 举报
回复
还是没人来呀!!!!!!!!!!!
龙宜坡 2009-11-07
  • 打赏
  • 举报
回复
貌似有点逆波兰式的意思!
lizhigang770 2009-11-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 angel6709 的回复:]
^是异或
要用到反射。
[/Quote]

这里是数学公式不是程序里的异或符号
angel6709 2009-11-06
  • 打赏
  • 举报
回复
^是异或
要用到反射。
aimeast 2009-11-06
  • 打赏
  • 举报
回复
要不是个无聊贴,要不会被推荐。

使用栈来存储,使用工厂模式
Aslangg 2009-11-06
  • 打赏
  • 举报
回复
帮顶 好长~
lizhigang770 2009-11-06
  • 打赏
  • 举报
回复
没人顶啊

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧