用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - c#代码库

表达式计算(堆栈)

2012-10-08 作者: 神马举报

[c#]代码库

/******************************************************************
   * 创 建 人:  SamWang
   * 创建时间:  2011-11-29
   * 描    述:
   *             计算器类:能直接对表达式进行计算,支持变量
   * 原    理:  将表达式按字符压入堆栈中,然后按照各操作符的级别进行处理
   * 版    本:  V1.0
   * 环    境:  VS2005
  ******************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
 
namespace LingDang.CRM.UI.Client
{
public class Calculator
{
    private string _expression;
    private Stack s;
    private string[] values;
 
    ///
    /// 构造函数
    ///
    /// 表达式
    /// 变量值数组
    public Calculator ( string expression, string[] varValues )
    {
        this._expression = expression.ToLower();
        s = new Stack();
        values = varValues;
    }
 
    ///
    /// 构造函数
    ///
    /// 表达式
    public Calculator ( string expression )
    {
        this._expression = expression;
        s = new Stack();
    }
 
    ///
    /// 总运行
    ///
    ///
    public double Run()
    {
        string expression = PostFix();
        string[] aryString = expression.Split ( '|' );
 
        foreach ( string str in aryString )
        {
            if ( IsNumber ( str ) || IsVarible ( str[0] ) )
            {
                double d;
                if ( IsVarible ( str[0] ) )
                {
                    d = Convert.ToDouble ( GetValue ( str[0] ) );
                }
                else
                {
                    d = Convert.ToDouble ( str.ToString() );
                }
                AddOperands ( d );
            }
            else
            {
                DoOperator ( str );
            }
 
        }
        return ( double ) s.Pop();
    }
 
 
    private bool IsNumber ( string str )
    {
        if ( str.Length > 1 )
        {
            return true;
        }
        else
        {
            return Char.IsDigit ( str[0] );
        }
    }
 
    ///
    /// 判断是否为变量,变量范围为a-z
    ///
    ///
    ///
    private bool IsVarible ( char c )
    {
        if ( c >= 'a' && c <= 'z' )
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
 
    private void AddOperands ( double val )
    {
        s.Push ( val );
    }
 
    ///
    /// 得到公式左右运算数
    ///
    ///
    ///
    ///
    private bool GetTwoOperands ( out double left, out double right )
    {
        try
        {
            right = ( double ) s.Pop();
            left = ( double ) s.Pop();
        }
        catch ( InvalidOperationException )
        {
            right = 0;
            left = 0;
            return false;
        }
        return true;
    }
 
    ///
    /// 计算操作
    ///
    /// 运算符
    private void DoOperator ( string op )
    {
        double left, right;
        bool result = GetTwoOperands ( out left, out right );
        if ( result )
        {
            switch ( op )
            {
            case "+":
                s.Push ( left + right );
                break;
            case "-":
                s.Push ( left - right );
                break;
            case "*":
                s.Push ( left * right );
                break;
            case "/":
                if ( right == 0.0 )
                {
                    s.Clear();
                    //Divide by 0!
                    throw new Exception ( "除数不能为零" );
                }
                else
                    s.Push ( left / right );
                break;
            case "^":
                s.Push ( Math.Pow ( left, right ) );
                break;
            }
        }
        else
        {
            s.Clear();
        }
    }
 
    ///
    /// 解析为后缀表达式
    ///
    ///
    public string PostFix()
    {
        string str = this._expression + "#";
        char tempc;
        char[] chars = str.ToCharArray();
        Stack ts = new Stack();
        ts.Push ( '#' );
        string str1 = "";
        string tmpStr = "";
        bool isNum = false;
        foreach ( char c in chars )
        {
            if ( Char.IsDigit ( c ) || IsVarible ( c ) || c == '.' )
            {
                tmpStr += c.ToString();
                isNum = true;
            }
            else
            {
                if ( isNum )
                {
                    str1 += tmpStr + "|";
                    tmpStr = "";
                }
                isNum = false;
                if ( c == ')' )
                {
                    for ( tempc = Convert.ToChar ( ts.Pop() ); tempc != '('; tempc = Convert.ToChar ( ts.Pop() ) )
                        str1 += tempc.ToString() + "|";
                }
                else
                {
                    for ( tempc = Convert.ToChar ( ts.Pop() ); Isp ( tempc ) > Icp ( c ); tempc = Convert.ToChar ( ts.Pop() ) )
                        str1 += tempc.ToString() + "|";
                    ts.Push ( tempc );
                    ts.Push ( c );
                }
            }
        }
        return str1.Substring ( 0, str1.Length - 1 );
    }
 
    ///
    /// 根据变量名得到对应的值
    ///
    /// 变量名:A-Z
    ///
    private string GetValue ( char c )
    {
        string result = "0";
        //变量对应的数组位置
        int index = Convert.ToInt32 ( c ) - Convert.ToInt32 ( 'a' );
        if ( index < values.Length )
        {
            result = values[index].ToString();
        }
        return result;
    }
 
    private int Isp ( char c )
    {
        int k;
        switch ( c )
        {
        case '#':
            k = 0;
            break;
        case '(':
            k = 1;
            break;
        case '^':
            k = 7;
            break;
        case '*':
        case '/':
        case '%':
            k = 5;
            break;
        case '+':
        case '-':
            k = 3;
            break;
        case ')':
            k = 8;
            break;
        default:
            //Unknown operator!
            throw new Exception ( "无效操作符:"+c.ToString() );
        }
        return k;
    }
 
    private int Icp ( char c )
    {
        int k;
        switch ( c )
        {
        case '#':
            k = 0;
            break;
        case '(':
            k = 8;
            break;
        case '^':
            k = 6;
            break;
        case '*':
        case '/':
        case '%':
            k = 4;
            break;
        case '+':
        case '-':
            k = 2;
            break;
        case ')':
            k = 1;
            break;
        default:
            //Unknown operator!
            throw new Exception ( "无效操作符:" + c.ToString() );
        }
        return k;
    }
}
}


网友评论    (发表评论)


发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...