用户注册



邮箱:

密码:

用户登录


邮箱:

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

发表随想


还能输入: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、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

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

加载中,请稍后...