直接看代码,里面有注释。
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Scan_demo
{
/*(一)类名:CalculateString
* 功能:计算表达式字符串的值。当前支持的运算符包括加(+)减(-)乘(*)除(/)幂(^),支持圆括号(),支持小数。
* 例如:输入字符串" -(369.9+(- (- 55 *6))) + 2.5*3^2",计算后得到数字-677.2
*
*(二)使用的工具类及其功能:
* string: 存放输入的字符串;
* Regex: 检查语法;
* StringBuilder:对字符串进行预处理,如去掉空格、添加分隔符。再利用string类的Split方法把字符串分解为字符串数组。
* Stack:利用其记忆功能,处理计算中的优先级问题。
* double:把字符串转成double数值
*
*(三)主要算法:
* 1、生成后缀表达式;
* 2、计算后缀表达式;
*
*/
class CalculateString
{
/// <summary>
/// 计算字符串表达式的值。
/// </summary>
/// <param name="exp">输入的表达式字符串</param>
/// <returns>返回计算值,为double类型</returns>
public static double Compute(string exp)
{
if (!checkRules(exp))
{
throw new FormatException("字符串为空或不合法");
}
//先把字符串转换成后缀表达式字符串数组
string[] rpn = toRPN(toStrings(exp));
//再计算后缀表达式
Stack<double> stack = new Stack<double>(); //存放参与计算的数值、中间值、结果
//算法:利用foreach来扫描后缀表达式字符串数组,得到数值则直接压入栈中,
//得到运算符则从栈顶取出两个数值进行运算,并把结果压入栈中。最终栈中留下一个数值,为计算结果。
foreach (string oprator in rpn)
{
//为什么总是弹出两个数值?因为都是双目运算。
//先弹出的是运算符右边的数,弹出两个数值后注意运算顺序。
switch (oprator)