ChinaDHF
学而不思则罔,思而不学则殆。
posts - 41,  comments - 219,  trackbacks - 5
    最近要写一个工资管理软件,不可避免的要用到公式的定义及求值等问题。对于数学表达式的计算,虽然也有直接对表达式进行扫描并按照优先级逐步计算的方法,但感觉还是不如将中缀表达式转换为逆波兰表达式更容易处理。
    使用逆波兰表达式,则有以下几件工作需要去做:
    1.对中缀表达式进行语法分析,或称合法性检查。
    2.将中缀表达式转换为逆波兰表达式。
    3.计算逆波兰表达得到我们想要的值。
以下是我为实现该功能而写的一个简单的类:
using System;
using System.Text;
using System.Collections;
using System.Text.RegularExpressions;

namespace Seaking
{
    
public class RpnExpression
    
{
        
检查中缀表达式的合法性数字
            string exMatch=@"^0([-+*/]0)*$";//匹配无括号的、用
0替换所有的数字后的表达式
            
            exp
=Regex.Replace(exp,numberMatch,"0");//为简化检测,用0替换所有的数字
            while(Regex.IsMatch(exp,pMatch))
            
{
                
foreach(Match match in Regex.Matches(exp,pMatch))
                
{
                    
string tmp=match.Value;
                    tmp
=tmp.Substring(1,tmp.Length-2);//去掉 "("和 ")"
                    if(!Regex.IsMatch(tmp,exMatch)) return false;
                }

                exp
=Regex.Replace(exp,pMatch,"0");//将最内层的括号及括号内表达式直接用一个0代替
            }


            
return Regex.IsMatch(exp,exMatch);
        }

        
#endregion

        
生成逆波兰表达式

        
计算逆波兰表达式的值
    }

}

    由于只是工资计算,该类只支持+-×/ 四种运算,而且不支持负数(太麻烦,呵呵),有兴趣的朋友可以自己扩充一下。
posted on 2006-07-16 10:01 东海风 阅读(4002) 评论(10)  编辑 收藏

FeedBack:
2006-07-16 10:50 | 享受工作,享受生活      
这么专业 :)
  回复  引用  查看    
2006-07-16 11:31 | ywer [未注册用户]
赫赫有名
  回复  引用    
#3楼 [楼主]
2006-07-16 11:37 | 东海风      
楼上两位过于客气了。共同学习……
  回复  引用  查看    
2006-07-17 09:39 | 达达      
用CodeDom做个动态编译好像也可以解决问题,楼主认为呢?
  回复  引用  查看    
#6楼 [楼主]
2006-07-17 15:38 | 东海风      
@达达
好象最近对CodeDom特别感兴趣啊,不知研究的怎么样了?
我对CodeDom不了解,我想这种解决方式应该是可行的,但是对中缀表达的语法要求严格一些,最好也是事先做一下合法性检测,是吗?

  回复  引用  查看    
2006-07-17 20:33 | 达达      
@东海风
呵呵,还没深入研究过.
用动态编译时应该可以抛出异常,当然我还是比较赞同你的正则匹配方式.
  回复  引用  查看    
2007-06-15 10:08 | 吉林 [未注册用户]

  回复  引用    
2007-12-03 17:49 | Koy      
不错,值得学习下!
  回复  引用  查看    
2008-09-30 15:51 | CowNew开源团队      
与逆波兰表达式的常见面试题及答案请参考:http://www.jsj321.com/forum/viewthread.php?tid=199&extra=page%3D1&frombbs=1
  回复  引用  查看    

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *