Ejemplo n.º 1
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;
        }
Ejemplo n.º 2
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;
        }
Ejemplo n.º 3
0
 /// <summary>
 /// 抛出异常
 /// </summary>
 /// <param name="pos">异常在运算因子列表中的位置</param>
 private void MakeException(int pos, Exception ex)
 {
     List<CalVal> tempValList = new CalValList(nomalStringExpression).valList;
     throw (new Exception(ex.Message
         + "|:" + tempValList[pos].ope.tag
         + "|:" + BackToStrExp(pos, tempValList).Length.ToString()));
 }
Ejemplo n.º 4
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;
        }
Ejemplo n.º 5
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;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 存储函数
        /// </summary>
        /// <param name="expr">存储还是替换</param>
        /// <returns>是否存储成功</returns>
        private bool StoreFun(string expr)
        {
            try
            {
                //记录表达式
                string tempExpr = funExpr.Text;
                bool hasAnnotate;//表达式是否有注释
                //删除注释
                tempExpr = Common.DeleteAnnotate(funExpr.Text, out hasAnnotate);
                //生成运算因子列表,此过程可以检查表达式是否合法
                //若不合法会抛出异常
                CalValList valList = new CalValList(tempExpr);

                //存储函数
                string strFun = txtFunName.Text.Trim()
                    + "|" + txtDesc.Text.Trim()
                    + "|" + funExpr.Text.Trim()
                    + "|" + txtFunVars.Text.Trim()
                    + "|" + (cmbFunSort.Text.Trim() == "" ? "其它" : cmbFunSort.Text.Trim());
                if (Properties.Settings.Default.funList == null)//判断是否为null
                {
                    Properties.Settings.Default.funList = new StringCollection();
                }
                Properties.Settings.Default.funList.Add(strFun);
                Properties.Settings.Default.Save();

                if (expr == "重命名")
                {
                    MessageBox.Show("函数'" + listBox_FunList.SelectedItem.ToString().Split('(')[0] + "'已重命名为'" + txtFunName.Text + "'", "提示");
                    return true;
                }
                MessageBox.Show("函数'" + txtFunName.Text.Trim() + ":" + funExpr.Text.Trim() + "'\n\n" + expr + "成功!", "提示");
                return true;
            }
            catch
            {
                MessageBox.Show("存储失败", "提示");
                return false;
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 参数变量列表是否合法
        /// </summary>
        private bool isVarsLegit(out string desc)
        {
            desc = "合法";
            txtFunVars.Text = txtFunVars.Text.Replace(" ", "");
            string[] str = txtFunVars.Text.Trim().Split(',');
            for (int i = 0; i < str.Length; i++)
            {
                //参数变量列表不合法
                if (str[i] == "")
                {
                    desc = "参数变量列表不合法";
                    return false;
                }
                //参数变量不能以数字开头
                int n;
                if (int.TryParse(str[i][0].ToString(), out n))
                {
                    desc = "参数变量不能以数字开头";
                    return false;
                }
                //参数变量不能是已存在的函数或常量
                CalOpeList opeList = new CalOpeList();
                CalOpe ope = opeList.GetOpe(str[i]);
                if (ope != null)
                {
                    desc = "参数变量不能是已存在的函数、变量或常量";
                    return false;
                }

                #region 参数变量个数是否与函数表达式中参数变量个数匹配
                //记录表达式
                string tempExpr = funExpr.Text;
                bool hasAnnotate;//表达式是否有注释
                //删除注释
                tempExpr = Common.DeleteAnnotate(funExpr.Text, out hasAnnotate);
                //生成运算因子列表,此过程可以检查表达式是否合法
                //若不合法会抛出异常
                CalValList valList = new CalValList(tempExpr);
                if (!hasAnnotate)//没有注释
                {
                    funExpr.Text = valList.nomalStringExpression;
                }

                List<string> strVarList = new List<string>();//记录表达式中的参数
                //扫描运算因子列表
                for (int k = 0; k < valList.valList.Count; k++)
                {
                    //如果当前运算因子的类型是值类型
                    if (valList.valList[k].type == ValType.Number)
                    {
                        double d;
                        //如果值类型无法转换为数字
                        if (!double.TryParse(valList.valList[k].num.stringValue, out d))
                        {
                            //且没有大于或小于号,为了支持分段函数
                            if (valList.valList[k].num.stringValue.IndexOf("<") == -1
                                && valList.valList[k].num.stringValue.IndexOf(">") == -1)
                            {
                                strVarList.Add(valList.valList[k].num.stringValue);
                            }
                        }
                    }
                }
                //删除重复
                for (int m = 0; m < strVarList.Count; m++)
                {
                    //逐个扫描当前参数变量后面的参数变量
                    for (int k = m + 1; k < strVarList.Count; k++)
                    {
                        if (strVarList[k] == strVarList[m])//存在相同的
                        {
                            strVarList.RemoveAt(k--);//删除相同的变量,注意调整k的值
                        }
                    }
                }
                //如果参数变量个数与函数表达式中参数变量个数不相等
                if (strVarList.Count != txtFunVars.Text.Trim().Split(',').Length)
                {
                    desc = "存储失败!\n\n参数变量过多或过少";
                    return false;
                }
                //检测变量是否对应
                //扫描从表达式中取出的每一个函数变量
                string[] strParameterList = txtFunVars.Text.Trim().Split(',');
                for (i = 0; i < strVarList.Count; i++)
                {
                    bool exists = false;
                    for (int m = 0; m < strParameterList.Length; m++)
                    {
                        if (strVarList[i] == Common.DeleteAnnotate(strParameterList[i], out hasAnnotate))
                        {
                            exists = true;
                            break;
                        }
                    }
                    if (!exists)
                    {
                        desc = "存储失败!\n\n表达式中的变量与参数列表中的变量不对应";
                        return false;
                    }
                }
                #endregion

            }
            return true;
        }