/// <summary>
        /// 单步计算
        /// </summary>
        /// <returns>单步计算结果</returns>
        public CalResult CalculateOneStep()
        {
            CalResult result = null;
            int currentPos = -1;

            try
            {
                #region 优先级列表为空的情况
                //优先级列表不存在的情况
                if (levelList.Count == 0)
                {
                    #region 完成计算后(优先级列表为空,无需计算),删除逗号
                    //扫描运算因子列表,删除逗号
                    for (int i = 0; i < valList.Count; i++)
                    {
                        //找到逗号
                        if (valList[i].OpeType == OpeType.Separator)
                        {
                            this.valList.RemoveAt(i);
                            //调整i
                            i--;
                        }
                    }
                    #endregion

                    #region 完成计算后(优先级列表为空,无需计算),删除括号
                    //扫描运算因子列表,删除括号
                    for (int i = 0; i < valList.Count; i++)
                    {
                        //找到括号
                        if (valList[i].OpeType == OpeType.leftParenthesis
                            || valList[i].OpeType == OpeType.rightParenthesis)
                        {
                            this.valList.RemoveAt(i);
                            //调整i
                            i--;
                        }
                    }
                    #endregion

                    if (valList.Count == 1)//一个计算结果
                    {
                        //该运算因子是数字
                        if (valList[0].type == ValType.Number)
                        {
                            double r;
                            //如果无法转换成double值
                            if (!double.TryParse(valList[0].num.stringValue, out r))
                            {
                                throw new Exception("请输入正确的表达式");
                            }
                        }

                        result = new CalResult();
                        result.numList.Add(valList[0].num);
                    }
                    else//多个计算结果
                    {
                        result = new CalResult();
                        for (int i = 0; i < valList.Count; i++)
                        {
                            //该运算因子是数字
                            if (valList[i].type == ValType.Number)
                            {
                                double r;
                                //如果无法转换成double值
                                if (!double.TryParse(valList[i].num.stringValue, out r))
                                {
                                    throw new Exception("请输入正确的表达式");
                                }
                            }

                            result.numList.Add(valList[i].num);
                        }
                    }

                    return result;
                }
                #endregion

                #region 核心算法,对于当前优先级,扫描运算因子列表并计算
                if (levelList.Count != 0)//优先级列表不为空
                {
                    #region 处理当前优先级
                    //对于当前优先级,逐个扫描运算因子,处理具有该优先级的运算
                    for (int i = 0; i < valList.Count; i++)
                    {
                        //找到具有该优先级的运算符
                        if (valList[i].type == ValType.Operator
                            && valList[i].level == levelList[0])//该运算因子的优先级等于当前优先级
                        {
                            bool isSign = false;//Sign为true表示当前运算因子是正负号
                            currentPos = valList[i].primalPos;//记录当前运算因子在列表中的原始位置

                            //参数列表
                            List<CalNum> numList = new List<CalNum>();
                            //临时计算结果
                            CalNum num;

                            switch (valList[i].OpeType)//i表示该运算因子的位置
                            {
                                #region case OpeType.PlusOrMinus:
                                case OpeType.PlusOrMinus:
                                    //若该运算符前面没有运算因子
                                    //或前一个运算因子是运算符,则按正负号计算
                                    if (i == 0 || (i - 1 >= 0 && valList[i - 1].type == ValType.Operator))
                                    {
                                        isSign = true;//是正负号
                                        //获取该运算符的参数
                                        if (i + 1 < valList.Count && valList[i + 1].type == ValType.Number)
                                        {
                                            //注意,下面第一句不可省略
                                            numList = new List<CalNum>();

                                            numList.Add(valList[i + 1].num);
                                        }

                                        //计算
                                        num = CalOpeList.Calculate(valList[i].ope, numList);
                                        //更新运算因子列表
                                        ReplaceVal(num, 2, i);

                                        //i无需调整
                                    }
                                    else//若前一个运算因子是操作数,则按加减号计算
                                    {
                                        //获取该运算符的参数
                                        if (valList[i - 1].type == ValType.Number
                                            && i + 1 < valList.Count && valList[i + 1].type == ValType.Number)
                                        {
                                            //注意,下面第一句不可省略
                                            numList = new List<CalNum>();

                                            numList.Add(valList[i - 1].num);
                                            numList.Add(valList[i + 1].num);
                                        }

                                        //计算
                                        num = CalOpeList.Calculate(valList[i].ope, numList);
                                        //更新运算因子列表
                                        ReplaceVal(num, 3, i - 1);
                                        //调整i
                                        i--;
                                    }
                                    break;
                                #endregion

                                #region case OpeType.bothSides:
                                case OpeType.bothSides:
                                    //获取该运算符的参数
                                    if (i >= 1 && valList[i - 1].type == ValType.Number
                                        && i + 1 < valList.Count && valList[i + 1].type == ValType.Number)
                                    {
                                        //注意,下面第一句不可省略
                                        numList = new List<CalNum>();

                                        numList.Add(valList[i - 1].num);
                                        numList.Add(valList[i + 1].num);
                                    }

                                    //计算
                                    num = CalOpeList.Calculate(valList[i].ope, numList);
                                    //更新运算因子列表
                                    ReplaceVal(num, 3, i - 1);
                                    //调整i
                                    i--;
                                    break;
                                #endregion

                                #region case OpeType.left:
                                case OpeType.left:
                                    //获取该运算符的参数
                                    if (i >= 1 && valList[i - 1].type == ValType.Number)
                                    {
                                        //注意,下面第一句不可省略
                                        numList = new List<CalNum>();

                                        numList.Add(valList[i - 1].num);
                                    }

                                    //计算
                                    num = CalOpeList.Calculate(valList[i].ope, numList);
                                    //更新运算因子列表
                                    ReplaceVal(num, 2, i - 1);
                                    //调整i
                                    i--;
                                    break;
                                #endregion

                                #region case OpeType.noParameter:
                                case OpeType.noParameter:
                                    //注意,下面第一句不可省略
                                    numList = new List<CalNum>();

                                    //计算
                                    num = CalOpeList.Calculate(valList[i].ope, numList);
                                    //更新运算因子列表
                                    ReplaceVal(num, 1, i);
                                    break;
                                #endregion

                                #region case OpeType.right:
                                case OpeType.right:
                                    #region 该运算符只有一个参数,且它的右边是常数
                                    if (i + 1 < valList.Count
                                        && valList[i].ParameterNumber == 1
                                        && valList[i + 1].type == ValType.Number)
                                    {
                                        //获取该运算符的参数
                                        //注意,下面第一句不可省略
                                        numList = new List<CalNum>();
                                        numList.Add(valList[i + 1].num);

                                        //计算
                                        num = CalOpeList.Calculate(valList[i].ope, numList);
                                        //更新运算因子列表
                                        ReplaceVal(num, 2, i);
                                    }
                                    #endregion

                                    #region 该运算符不是只有一个参数,或者它的右边不是常数
                                    else
                                    {
                                        //计算参数个数
                                        int count = 0;

                                        int k = i + 1;
                                        //从运算符后面开始检测
                                        //如果是左括号、分隔符或数字,则执行while中语句
                                        while (k < valList.Count
                                            && (valList[k].type == ValType.Number
                                            || valList[k].OpeType == OpeType.Separator
                                            || valList[k].OpeType == OpeType.leftParenthesis))
                                        {
                                            //如果是数字,参数个数加1
                                            if (valList[k].type == ValType.Number)
                                            {
                                                count++;
                                            }
                                            k++;
                                        }

                                        //注意,下面第一句不可省略
                                        numList = new List<CalNum>();

                                        //从该运算符后面,逐个扫描,获取该运算符的参数
                                        //j表示已读取的参数个数
                                        //m表示检测位置增量
                                        int m = 0;
                                        for (int j = 0; j < count; )
                                        {
                                            //如果找到数字,存为参数
                                            if (valList[i + j + m + 1].type == ValType.Number)
                                            {
                                                numList.Add(valList[i + j + m + 1].num);
                                                j++;
                                            }
                                            //如果是分隔符或左括号,检测位置增量加1,表示跳过该运算因子,继续检测
                                            else if (valList[i + j + m + 1].OpeType == OpeType.Separator
                                                || valList[i + j + m + 1].OpeType == OpeType.leftParenthesis)
                                            {
                                                m++;
                                            }
                                        }

                                        //计算
                                        num = CalOpeList.Calculate(valList[i].ope, numList);
                                        //更新运算因子列表,count+m+2中的2表示运算符本身和右括号
                                        ReplaceVal(num, count + m + 2, i);
                                    }
                                    #endregion

                                    break;

                                #endregion

                            }//end switch

                            if (!isSign)//如果不是正负号
                            {
                                break;//退出for循环
                            }
                        }
                    }
                    #endregion

                    #region 删除处理完的优先级
                    bool levelExists = false;//是否存在具有该优先级的运算符
                    //逐个扫描运算因子,判断是否仍存在具有该优先级的运算符
                    for (int i = 0; i < valList.Count; i++)
                    {
                        if (levelList[0] == valList[i].level)//存在
                        {
                            levelExists = true;
                        }
                    }
                    if (!levelExists)//该优先级已处理完则删除它
                    {
                        levelList.RemoveAt(0);
                    }
                    #endregion

                }
                #endregion

                #region 处理计算结果
                //处理计算结果
                if (levelList.Count == 0)//全部优先级已经处理完毕
                {
                    #region 完成计算后,删除逗号
                    //扫描运算因子列表,删除逗号
                    for (int i = 0; i < valList.Count; i++)
                    {
                        //找到逗号
                        if (valList[i].OpeType == OpeType.Separator)
                        {
                            this.valList.RemoveAt(i);
                            //调整i
                            i--;
                        }
                    }
                    #endregion

                    #region 完成计算后,删除括号
                    //扫描运算因子列表,删除括号
                    for (int i = 0; i < valList.Count; i++)
                    {
                        //找到括号
                        if (valList[i].OpeType == OpeType.leftParenthesis
                            || valList[i].OpeType == OpeType.rightParenthesis)
                        {
                            this.valList.RemoveAt(i);
                            //调整i
                            i--;
                        }
                    }
                    #endregion

                    if (valList.Count == 1)//一个计算结果
                    {
                        result = new CalResult();
                        result.numList.Add(valList[0].num);
                    }
                    else//多个计算结果
                    {
                        result = new CalResult();
                        for (int i = 0; i < valList.Count; i++)
                        {
                            result.numList.Add(valList[i].num);
                        }
                    }
                }
                else//全部优先级未处理完
                {
                    result = new CalResult();
                    result.numList.Add(new CalNum(BackToStrExp()));//剩下的运算因子列表转换成string后作为计算结果返回
                }
                #endregion

            }
            catch (Exception ex)
            {
                if (currentPos != -1)
                {
                    MakeException(currentPos, ex);
                }
                else
                {
                    throw new Exception(ex.Message);
                }
            }

            return result;
        }
Beispiel #2
0
        /// <summary>
        /// 等于
        /// </summary>
        private void btnEqual_Click(object sender, EventArgs e)
        {
            //判断程序能否继续使用
            if (!Common.IsProgramPassValidate())
            {
                try
                {
                    RegisterForm regForm = new RegisterForm();
                    regForm.ShowDialog(this);
                    return;
                }
                catch
                {
                    return;
                }
            }

            try
            {
                if (this.语音ToolStripMenuItem1.Checked)
                {
                    //中止之前的计算结果发音
                    if (this.speechResultThread != null)
                    {
                        this.speechResultThread.Abort();
                        this.speechResultThread = null;
                    }
                }

                if (txtExp.Text.IndexOf("=") != -1)//存储变量
                {
                    memoryVars();
                }
                else//计算
                {
                    result = Calculate();//计算
                    ANS = result.GeneralResultToShow;//保存计算结果
                    txtResult.Text = ANS;//显示计算结果

                    //计算结果发音
                    if (this.语音ToolStripMenuItem1.Checked)
                    {
                        //起动线程发音
                        speechResultThread = new System.Threading.Thread(new System.Threading.ThreadStart(SpeechResult));
                        speechResultThread.Start();
                    }
                }
                txtExp.Focus();
                txtExp.SelectionStart = txtExp.Text.Length;
                isScientificShow = false;
                //记录表达式
                MemoryExpr_Cal();
            }
            catch (Exception ex)
            {
                //计算结果框中显示出错信息
                ShowException(ex);
            }
        }
Beispiel #3
0
        /// <summary>
        /// 计算表达式
        /// </summary>
        private CalResult Calculate()
        {
            CalValList valList = null;
            //记录表达式
            memoryExp = txtExp.Text;
            //删除注释
            txtExp.Text = Common.DeleteAnnotate(txtExp.Text, out hasAnnotate);
            //生成运算因子列表
            valList = new CalValList(txtExp.Text);
            //重新显示表达式
            if (hasAnnotate)//有注释
            {
                txtExp.Text = memoryExp;
            }
            else//没有注释
            {
                txtExp.Text = valList.nomalStringExpression;
            }

            CalResult result = null;
            if (this.单步计算ToolStripMenuItem.Checked)//单步计算
            {
                completeSteps++;
                for (int i = 0; i < completeSteps; i++)
                {
                    //优先级列表为空的情况
                    if (valList.levelList.Count == 0)
                    {
                        result = valList.CalculateOneStep();
                    }

                    if (valList.levelList.Count > 0)//如果优先级尚未处理完毕
                    {
                        result = valList.CalculateOneStep();
                    }
                }
            }
            else//一次性计算最终结果
            {
                result = valList.Calculate();//计算
            }

            return result;
        }
Beispiel #4
0
        /// <summary>
        /// txtExp文本框事件
        /// </summary>
        private void txtExp_TextChanged(object sender, EventArgs e)
        {
            try
            {
                _selectionStartPos = txtExp.SelectionStart;
                //如果调用了Common.SetWrongOpeColor将不再调用Common.SetColor
                if (!Common._lock)
                {
                    Common.SetColor(txtExp.Text, txtExp);
                }
                txtExp.SelectionStart = _selectionStartPos;

                //清空计算结果
                if (txtExp.Text.Trim() == "")
                {
                    result = null;
                }

                //发音
                if (this.语音ToolStripMenuItem1.Checked)
                {
                    //中止计算结果发音
                    if (this.speechResultThread != null)
                    {
                        this.speechResultThread.Abort();
                        this.speechResultThread = null;
                    }

                    if (this.isKeyDown)
                    {
                        string tag = txtExp.Text[txtExp.SelectionStart - 1].ToString();
                        switch (tag)
                        {
                            case "0":
                            case "1":
                            case "2":
                            case "3":
                            case "4":
                            case "5":
                            case "6":
                            case "7":
                            case "8":
                            case "9":
                                tag = "_" + tag;
                                break;
                            case ".":
                                tag = "点";
                                break;
                            case "+":
                                tag = "加上";
                                break;
                            case "-":
                                //是负号
                                if (Common.isSubtractive(txtExp.Text, tag, txtExp.SelectionStart))
                                {
                                    tag = "负";
                                }
                                else
                                {
                                    tag = "减去";
                                }
                                break;
                            case "*":
                                tag = "乘以";
                                break;
                            case "/":
                                tag = "除以";
                                break;
                        }
                        Common.Speech(tag);
                        this.isKeyDown = false;
                    }
                }
            }
            catch { }
        }