码迷,mamicode.com
首页 > 其他好文 > 详细

先贴一段上学时候写的代码占个位

时间:2016-05-25 22:09:40      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:

C#计算器

using System;
using System.Collections.Generic;
using System.Linq;

namespace System
{
    /// <summary>
    /// 计算器类
    /// </summary>
    public class Calculator
    {
        string strFormula;

        /// <summary>
        /// 用一个字符串表达式初始化实例。
        /// </summary>
        /// <param name="strFormula"></param>
        public Calculator(string strFormula)
        {
            this.strFormula = strFormula;
        }
        public Calculator()
        {

        }

        /// <summary>
        /// 表达式结果。如果没有用有效表达式初始化实例,则结果为0。
        /// </summary>
        public double Result
        {
            get
            {
                if (strFormula == null || strFormula == string.Empty)
                    return 0;
                else
                    return Calculate(Scan(strFormula));
            }
        }

        /// <summary>
        /// 静态方法,用于计算一个字符串表达式。
        /// </summary>
        /// <param name="formula">字符串表达式</param>
        /// <returns></returns>
        public static double Calculate(string formula)
        {
            var cal = new Calculator();
            return cal.Calculate(cal.Scan(formula));
        }

        /// <summary>
        /// 扫描字符串,生成表达式元素队列。
        /// </summary>
        /// <param name="formula">表达式字符串</param>
        /// <returns>表达式队列</returns>
        protected List<object> Scan(string formula)
        {
            List<object> formulaList = new List<object>();
            bool numFlag = false;
            int numStartIndex = 0;

            for (int i = 0; i < formula.Length; i++)
            {
                //判断是否为非法字符
                if (IllegalChar(formula[i]))
                {
                    throw new Exception("存在非法字符。");
                }

                //进行数字匹配
                if ((numFlag == false) && ((char.IsNumber(formula[i]) == true) || formula[i] == .))
                {
                    numFlag = true;
                    numStartIndex = i;
                }

                if ((numFlag == true) && (char.IsNumber(formula[i]) == false) && formula[i] != .)
                {
                    numFlag = false;
                    formulaList.Add(double.Parse(formula.Substring(numStartIndex, i - numStartIndex)));
                }

                //进行运算符匹配
                if (IsFormulaOperaor(formula[i]))
                {
                    formulaList.Add(formula[i].ToString());
                }

            }

            //对标志进行最后一轮收尾操作
            if (numFlag)
            {
                formulaList.Add(double.Parse(formula.Substring(numStartIndex)));
            }

            return formulaList;
        }

        /// <summary>
        /// 计算经过扫描形成的算术队列
        /// </summary>
        /// <param name="formula">算术队列</param>
        /// <returns></returns>
        protected double Calculate(List<object> formula)
        {
            //扫描并递归子表达式
            ushort deep = 0;
            int StartIndex = 0;
            for (int i = 0; i < formula.Count; i++)
            {
                checked
                {
                    if (formula[i].ToString() == "(")
                    {
                        if (deep == 0)
                        {
                            StartIndex = i;
                        }
                        deep++;
                    }
                    if (formula[i].ToString() == ")")
                    {
                        deep--;
                        if (deep == 0)
                        {
                            //递归子表达式 Skip Take
                            var result = Calculate(formula.Skip(StartIndex + 1).Take(i - StartIndex - 1).ToList());
                            //替换值
                            formula[StartIndex] = result;
                            //移除子表达式,StartIndex + 1 ~ i + 1
                            formula.RemoveRange(StartIndex + 1, i - StartIndex);
                            //重新设置新的开始位置
                            i = StartIndex;
                        }
                    }
                }
            }


            //优化表达式
            OptimizeFormula(ref formula);

            //进行运算
            //进行乘除运算
            for (int i = 1; i < formula.Count; i++)
            {
                if (formula[i].ToString() == "*")
                {
                    if (formula[i - 1] is double && formula[i + 1] is double)
                    {
                        formula[i - 1] = (double)formula[i - 1] * (double)formula[i + 1];
                        formula.RemoveRange(i--, 2);
                    }
                    else
                    {
                        throw new Exception("表达式不合法,连续出现运算符");
                    }
                }

                if (formula[i].ToString() == "/")
                {
                    if (formula[i - 1] is double && formula[i + 1] is double)
                    {
                        formula[i - 1] = (double)formula[i - 1] / (double)formula[i + 1];
                        formula.RemoveRange(i--, 2);
                    }
                    else
                    {
                        throw new Exception("表达式不合法,连续出现运算符");
                    }
                }

            }

            //进行加减运算
            for (int i = 1; i < formula.Count; i++)
            {
                if (formula[i].ToString() == "+")
                {
                    if (formula[i - 1] is double && formula[i + 1] is double)
                    {
                        formula[i - 1] = (double)formula[i - 1] + (double)formula[i + 1];
                        formula.RemoveRange(i--, 2);
                    }
                    else
                    {
                        throw new Exception("表达式不合法,连续出现运算符");
                    }
                }

                if (formula[i].ToString() == "-")
                {
                    if (formula[i - 1] is double && formula[i + 1] is double)
                    {
                        formula[i - 1] = (double)formula[i - 1] - (double)formula[i + 1];
                        formula.RemoveRange(i--, 2);
                    }
                    else
                    {
                        throw new Exception("表达式不合法,连续出现运算符");
                    }
                }

            }

            if (formula.Count != 1)
            {
                throw new Exception("表达式集合堆栈没有计算完全,这可能是因为表达式不正确造成的。");
            }

            return (double)formula[0];
        }

        /// <summary>
        /// 对表达式进行优化,同时检测表达式是否合法
        /// </summary>
        /// <param name="formula">表达式列表</param>
        protected void OptimizeFormula(ref List<object> formula)
        {
            if (formula[0].ToString() == "-" && formula[1] is double)
            {
                formula[1] = (double)formula[1] * -1;
                formula.RemoveAt(0);
            }

            if (IsArithmeticOperator(formula[0].ToString()) || IsArithmeticOperator(formula.Last().ToString()))
            {
                throw new Exception("表达式不正确");
            }

            for (int i = 1; i < formula.Count - 1; i++)
            {
                //判断是否为正负号
                if (formula[i].ToString() == "+" || formula[i].ToString() == "-")
                {
                    if (IsArithmeticOperator(formula[i - 1].ToString()) && formula[i + 1] is double)
                    {
                        //如果为符号与后面的数字合并
                        if (formula[i].ToString() == "-")
                        {
                            formula[i + 1] = (double)formula[i + 1] * -1;
                        }

                        //移除正负号表示位
                        formula.RemoveAt(i);
                    }
                }
            }

            for (int i = 1; i < formula.Count - 1; i++)
            {
                //两个运算符叠加在一起的情况
                if (formula[i].ToString() == "*" || formula[i].ToString() == "/")
                {
                    if (IsArithmeticOperator(formula[i - 1].ToString()) ||
                        IsArithmeticOperator(formula[i + 1].ToString())
                        )
                    {
                        throw new Exception("存在运算符错误");
                    }
                }
            }
        }

        /// <summary>
        /// 判断给定字符是否为非法字符
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        protected bool IllegalChar(char c)
        {
            return !("1234567890.+-*/() ".Contains(c));
        }

        /// <summary>
        /// 是否属于表达式运算符集的成员。
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        protected bool IsFormulaOperaor(char c)
        {
            return "+-*/()".Contains(c);
        }

        /// <summary>
        /// 是否为算术运算符。
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        protected bool IsArithmeticOperator(string c)
        {
            return "+,-,*,/".Split(,).Contains(c);
        }
    }
}

 

先贴一段上学时候写的代码占个位

标签:

原文地址:http://www.cnblogs.com/ssspecial/p/5528495.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!