易码技术论坛

 找回密码
 加入易码
搜索
查看: 179936|回复: 7

[C#]封装了一个四则运算的类

[复制链接]
发表于 2005-1-18 15:44:00 | 显示全部楼层
原来老F还在研究C#啊~~~
不过我记得运算算法不是要先转换成逆波兰式的吗?看了一下怎么没有这个感觉?[em07]
对C#不是很熟,看的也比较潦草,如果错了当我没说~~~
 楼主| 发表于 2005-1-18 22:32:00 | 显示全部楼层
楼上的好像是要考研的人吧?如果是,那么表叫我老F了……毕竟我还没有到考研的岁数……

呵呵,我这是土办法,自己瞎写的,效率比较低下。所以发上来希望能找到更好的方法~~

不知道那个逆波兰式要怎么搞?^_^bb

另外,这个只是四则运算,只支持+ - × / ()六种运算符号~~,简陋-_-b

[此贴子已经被作者于2005-1-19 8:00:59编辑过]

发表于 2005-1-19 14:25:00 | 显示全部楼层
就是把算式转换成这种格式
1+2    ------------->     +12
(1+2)*2 -------------> *2+12
读出一个算符并且连着两个两个数字就计算~~~
另:我不考研了,出了点事
又另:我觉得叫你老f很亲切的说~~
发表于 2005-1-19 17:17:00 | 显示全部楼层
代码看起来真亲切,C#和C++在语法上基本一样,只是有些用法不一样
  new ops("(",1),
   new ops(")",1),
   new ops("+",2),
   new ops("-",2),
   new ops("*",3),
   new ops("/",3)

C++中你用了NEW敢不delete
[em07]
方便多了
 楼主| 发表于 2005-1-19 18:41:00 | 显示全部楼层
实际上C++的程序返倒没有多写过~~

刚刚去查了查,Lasly说的逆波兰式相关资料我查到了。唉,没有系统的学过这些东西果然很郁闷-_-b

竟然有那么多名词不知道……先看看Lasly说的算法。

这个东西本来以为有错误,后来发现还是对的。晕……

[此贴子已经被作者于2005-1-24 10:16:19编辑过]

发表于 2005-3-10 22:43:00 | 显示全部楼层
以下是引用Lasly在2005-1-19 14:25:51的发言:
就是把算式转换成这种格式

1+2    ------------->     +12

(1+2)*2 -------------> *2+12

读出一个算符并且连着两个两个数字就计算~~~

另:我不考研了,出了点事

又另:我觉得叫你老f很亲切的说~~



怎么跟我们的数据结构上不太一样?

1+2==>1 2 +
(1+2)*3==>1 2 + 3 *
是这样吧?
发表于 2005-3-12 16:58:00 | 显示全部楼层
我记得转化用一个数据栈一个运算符栈
需要一个词法分析模块配合以下

有本编译原理的书里有原程序
 楼主| 发表于 2005-1-18 15:14:04 | 显示全部楼层 |阅读模式
写的不好,大家经管拍砖……。但是,请表说废话~~

类里面的两个主要部分
【calculate方法】:
输入一个字符串,只包含字符和四则运算符,返回结果。如果有非法字符,返回原字符串。主要是自己的程序里面需要这样的处理。如果要返回数字,直接调用workout方法就可以。
【workout方法】:
输入一个字符串,只包含字符和四则运算符,返回一个numitem类,包含运算符和值。

public class Calculate
{
  public class ops
  {
   public string name="";
   public int level=0;
   public ops(string iname,int ilevel){level=ilevel;name=iname;}
  }
  public class numItem
  {
   public int num,next;
   public ops op=new ops("",0);
  }
  public ops[] operators=
        {
   new ops("(",1),
   new ops(")",1),
   new ops("+",2),
   new ops("-",2),
   new ops("*",3),
   new ops("/",3)
  };
  public string calculate(string str)
  {
   for(int i=0;i<str.Length;i++)
   {
    if((str>='a'&&str<='z')||(str>='A'&&str<='Z')) return str;
    if(str<'0'||str>'9')
    {
     bool isWrong=true;
     foreach(ops j in operators)
     {
      if(j.name==str.Substring(i,j.name.Length)){isWrong=false;break;}
     }
     if(isWrong==true) return str;
    }
   }
       return workout(str,0).num.ToString();
  }

  //返回数字和它前面的符号
  private numItem getone(string str,int p)
  {
   numItem one=new numItem();
   //取数字
   int s=0;
   while( p+s<str.Length && str[p+s]<='9' && str[p+s]>='0') s++;
   one.next=p+s;
   for(int i=1;s>0;s--)
   {
    one.num+=(str[p+s-1]-'0')*i;
    i*=10;
   }
   //取算符
   p=one.next;
   foreach(ops i in operators)
   {
    if(p<str.Length && str.Substring(p,i.name.Length)==i.name)
    {
     one.op=i;
     p+=i.name.Length;
     break;
    }
   }
   one.next=p;
   if(one.op.name=="(") one=workout(str,one.next);
   return one;
  }
  public numItem workout(string str,int p)
  {
   numItem one=getone(str,p);
   int result=one.num;
   while(true)
   {
    numItem next=getone(str,one.next);
    if(next.op.level>one.op.level) next=workout(str,one.next);
    //运算
    if(one.op.name=="+")
    {
     result=next.num+one.num;
    }
    else if(one.op.name=="-")
    {
     result=one.num-next.num;
    }
    else if(one.op.name=="*")
    {
     result=next.num*one.num;
    }
    else if(one.op.name=="/")
    {
     result=one.num/next.num;
    }
    one=next;
    one.num=result;
    if(next.op.name=="")  return one;
    if(next.op.name==")")
    {
     one=getone(str,next.next);
     one.num=result;
     return one;
    }
   }
  }
}

[此贴子已经被作者于2005-1-18 15:15:19编辑过]

您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2025-6-17 06:07 , Processed in 0.011917 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表