Пример #1
0
        /// <summary>
        /// 分段函数
        /// </summary>
        private static CalNum subfuns(StringBuilder funExpr, List<CalNum> numList)
        {
            CalNum result = null;

            if (funExpr.ToString().IndexOf("subfuns(") == -1)
            {
                MakeException("分段函数语法不正确");
            }
            if (funExpr[funExpr.Length - 1] != ')')
            {
                MakeException("分段函数语法不正确");
            }
            funExpr.Replace("subfuns(", "");
            funExpr.Remove(funExpr.Length - 1, 1);
            CalNum num = numList[0];//仅支持对第一个参数分段

            bool isBeyond = true;//是否越界
            string[] funs = funExpr.ToString().Split(',');

            if (funs.Length % 3 != 0)
            {
                MakeException("subfuns的参数个数不正确,必须三个为一组");
            }

            for (int i = 0; i < funs.Length; i += 3)//每三个一组:左边界、右边界、对应表达式
            {
                double leftBoundary = double.MinValue;//左边界
                double rightBoundary = double.MaxValue;//右边界
                bool leftHollow = false;//左边界是否空心,默认是实心
                bool rightHollow = false;//右边界是否空心,默认是实心
                bool isIn = false;//参数是否在该范围内,默认false

                if (funs[i].IndexOf(">") != -1)//左边界空心
                {
                    leftHollow = true;
                    leftBoundary = double.Parse(funs[i].Substring(1));
                }
                else
                {
                    leftBoundary = double.Parse(funs[i]);
                }
                if (funs[i + 1].IndexOf("<") != -1)//右边界空心
                {
                    rightHollow = true;
                    rightBoundary = double.Parse(funs[i + 1].Substring(1));
                }
                else
                {
                    rightBoundary = double.Parse(funs[i + 1]);
                }

                #region 判断参数是否在当前范围内
                if (leftHollow == true)//左边界空心
                {
                    if (rightHollow == true)//右边界空心
                    {
                        if (num.DoubleValue > leftBoundary
                            && num.DoubleValue < rightBoundary)
                        {
                            isIn = true;
                        }
                    }
                    else//右边界实心
                    {
                        if (num.DoubleValue > leftBoundary
                            && num.DoubleValue <= rightBoundary)
                        {
                            isIn = true;
                        }
                    }
                }
                else//左边界实心
                {
                    if (rightHollow == true)//右边界空心
                    {
                        if (num.DoubleValue >= leftBoundary
                            && num.DoubleValue < rightBoundary)
                        {
                            isIn = true;
                        }
                    }
                    else//右边界实心
                    {
                        if (num.DoubleValue >= leftBoundary
                            && num.DoubleValue <= rightBoundary)
                        {
                            isIn = true;
                        }
                    }
                }
                #endregion

                if (isIn)//如果参数在当前范围内
                {
                    isBeyond = false;//没有越界
                    //计算
                    bool bl1;
                    string str = Common.DeleteAnnotate(funs[i + 2], out bl1);//删除注释
                    CalValList valList = new CalValList(str);
                    CalResult calResult = valList.Calculate();
                    if (calResult.numList.Count == 1)//一个计算结果
                    {
                        result = calResult.numList[0];
                    }
                    else//多个计算结果
                    {
                        result = new CalNum(calResult.GeneralResultToShow.Trim());
                    }
                    //跳出循环
                    break;
                }
            }
            if (isBeyond)
            {
                MakeException("输入的参数超出定义的范围");
            }

            return result;
        }
Пример #2
0
        /// <summary>
        /// 存储变量
        /// </summary>
        private void memoryVars()
        {
            string[] variables = Properties.Settings.Default.strVariables.Split('|');
            //进入该函数说明'='存在,下面两条语句不会出错
            string leftValue = txtExp.Text.Split('=')[0];
            string rightValue = txtExp.Text.Split('=')[1];
            //等号右边计算结果
            string rightResult = "";
            //支持存储15个变量
            int maxVarLength = 30;

            #region 赋值语句不合法的情况
            //确保只有一个'='
            if (txtExp.Text.Split('=').Length > 2)
            {
                txtResult.Text = "变量赋值语句不合法";
                return;
            }
            //左右值存在
            if (txtExp.Text.Split('=')[0].Trim() == ""
                || txtExp.Text.Split('=')[1].Trim() == "")
            {
                txtResult.Text = "变量赋值语句不合法";
                return;
            }
            //变量名称不合法的情况
            //变量名称中不能存在单引号
            if (leftValue.IndexOf("'") != -1)
            {
                txtResult.Text = "变量赋值语句不合法";
                return;
            }
            double d;
            //变量名称不能全为数字
            if (double.TryParse(leftValue, out d)
                || double.TryParse(leftValue.Substring(0, 1), out d))
            {
                txtResult.Text = "变量名称不合法";
                return;
            }
            //单引号必须成对出现,且最多只能有一对
            if (rightValue.Split('\'').Length != 1
                && rightValue.Split('\'').Length != 3)
            {
                txtResult.Text = "变量赋值语句不合法";
                return;
            }
            #endregion

            //计算等号右边
            if (rightValue[0] == '\'' && rightValue[rightValue.Length - 1] == '\'')
            {
                rightResult = rightValue.Replace("'", "");
            }
            else
            {
                CalValList valList = new CalValList(rightValue);
                rightResult = valList.Calculate().GeneralResultToShow.Replace(" ", "");
                txtExp.Text = leftValue + "=" + valList.nomalStringExpression;
            }

            if (variables.Length == 1)//特殊情况
            {
                Properties.Settings.Default.strVariables = leftValue + "|" + rightResult;
                Properties.Settings.Default.Save();
                txtResult.Text = "变量'" + leftValue + "'已赋值为'" + rightResult + "'";
            }
            else
            {

                #region 查找是否存在同名变量或同名运算符或常数
                bool homonymyOpe = false;
                bool varExists = false;
                int existsVarPos = -1;//同名变量位置

                //是否存在同名变量
                for (int i = 0; i < variables.Length; i += 2)
                {
                    //找到同名变量
                    if (variables[i] == leftValue)
                    {
                        existsVarPos = i;
                        varExists = true;
                        break;
                    }
                }

                //是否存在同名运算符
                CalOpeList opeList = new CalOpeList();
                for (int i = 0; i < opeList.count; i++)
                {
                    //找到同名运算符
                    if (opeList.opeList[i].tag == leftValue)
                    {
                        homonymyOpe = true;
                        break;
                    }
                }
                #endregion

                #region 存在同名变量,替换变量
                if (varExists)
                {
                    if (MessageBox.Show("变量'" + leftValue + "'已存在,且它的值为'"
                        + variables[existsVarPos + 1] + "',是否替换?", "提示", MessageBoxButtons.OKCancel)
                        == DialogResult.OK)
                    {
                        variables[existsVarPos + 1] = rightResult;
                        string s = variables[0];
                        for (int i = 1; i < variables.Length; i++)
                        {
                            s += "|" + variables[i];
                        }
                        Properties.Settings.Default.strVariables = s;
                        Properties.Settings.Default.Save();
                        txtResult.Text = "变量'" + leftValue + "'的值已替换为'" + rightResult + "'";
                    }
                }
                #endregion

                #region 存在同名常数或运算符
                else if (homonymyOpe)
                {
                    txtResult.Text = "存储变量失败!存在同名常数或运算符";
                }
                #endregion

                #region 不存在同名变量、常数或运算符,插入变量
                else
                {
                    //列表variables的开始读取位置
                    int startPos = -1;
                    //是否超出支持的最大变量个数
                    if (variables.Length < maxVarLength)
                    {
                        startPos = 0;
                    }
                    else
                    {
                        startPos = 2;
                        if (MessageBox.Show("存储的变量已达到最大个数\n\n若要添加新的变量,则需要删除旧变量'"
                            + variables[0] + "'(它的值为" + variables[1] + ")\n\n是否删除?",
                            "提示", MessageBoxButtons.OKCancel)
                            == DialogResult.Cancel)
                        {
                            txtResult.Text = "变量未存储!";
                            return;
                        }

                    }

                    string s = variables[startPos];
                    for (int i = startPos + 1; i < variables.Length; i++)
                    {
                        s += "|" + variables[i];
                    }

                    Properties.Settings.Default.strVariables = s
                            + "|" + leftValue + "|" + rightResult;
                    Properties.Settings.Default.Save();
                    txtResult.Text = "变量'" + leftValue + "'已赋值为'" + rightResult + "'";
                }
                #endregion

            }

            //更新变量菜单
            this.变量ToolStripMenuItem.DropDownItems.Clear();
            InsertVarsItem();
            //更新算式输入框右键菜单
            UpdateMenuRichTextBox();
            //更新文本框
            txtExp.Text = txtExp.Text;
        }
Пример #3
0
        /// <summary>
        /// 获取变量值或用户自定义函数的计算结果
        /// </summary>
        /// <param name="tag">变量标识符</param>
        private static CalNum GetVariableOrCustomFunResultValue(string tag, List<CalNum> numList)
        {
            CalNum result = null;

            if (numList.Count == 0)//变量
            {
                string[] variables = Properties.Settings.Default.strVariables.Split('|');

                //扫描变量键值列表
                for (int i = 0; i < variables.Length; i++)
                {
                    //找到变量
                    if (variables[i] == tag)
                    {
                        double d;
                        if (double.TryParse(variables[i + 1], out d))
                        {
                            result = new CalNum(d);
                        }
                        else
                        {
                            result = new CalNum(variables[i + 1]);
                        }
                    }
                }
            }
            else//用户自定义函数
            {
                try
                {
                    StringCollection funList = Properties.Settings.Default.funList;
                    if (funList != null)
                    {
                        //逐个扫描存在的函数,查找函数
                        for (int i = 0; i < funList.Count; i++)
                        {
                            if (funList[i].Split('|')[0] == tag)//找到函数
                            {
                                //参数个数不正确
                                if (numList.Count != funList[i].Split('|')[3].Split(',').Length)
                                {
                                    throw new Exception("|参数个数不正确");
                                }

                                string[] funParts = funList[i].Split('|');//分隔
                                StringBuilder funExpr = new StringBuilder(funParts[2]);//取出表达式

                                //替换表达式中的变量
                                for (int k = 0; k < numList.Count; k++)
                                {
                                    bool bl;
                                    //替换,用参数的stringValue替换且两边加上括号
                                    funExpr.Replace(Common.DeleteAnnotate(funParts[3].Split(',')[k], out bl), "(" + numList[k].stringValue + ")");
                                }

                                //分段函数
                                if (funExpr.ToString().IndexOf("subfuns") != -1)
                                {
                                    return subfuns(funExpr, numList);//不再进行后面的计算,返回
                                }

                                //计算
                                bool bl1;
                                string str = Common.DeleteAnnotate(funExpr.ToString(), out bl1);//删除注释
                                CalValList valList = new CalValList(str);
                                CalResult calResult = valList.Calculate();
                                if (calResult.numList.Count == 1)//一个计算结果
                                {
                                    result = calResult.numList[0];
                                }
                                else//多个计算结果
                                {
                                    result = new CalNum(calResult.GeneralResultToShow.Trim());
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message + "|(函数'" + tag + "'的表达式是'" + Common.GetFunExpr(tag) + "')");
                }
            }

            return result;
        }
Пример #4
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;
        }