/// <summary>
        /// 运算因子(数字、常数及运算符)列表合法性检查,并规范化
        /// </summary>
        private void ToNormalList()
        {
            CalOpeList opeList = new CalOpeList();

            #region 第一次处理
            //第一次处理,如sin2pi,转换成sin(2pi)
            for (int i = 0; i < valList.Count; i++)
            {
                //如果是数字
                if (valList[i].type == ValType.Number)
                {
                    //如果前面是左括号
                    if (i - 1 >= 0
                        && valList[i - 1].OpeType == OpeType.leftParenthesis)
                    {
                        continue;
                    }

                    //如果前面是一个参数的函数
                    if (i - 1 >= 0
                        && valList[i - 1].OpeType == OpeType.right
                        && valList[i - 1].ParameterNumber == 1)
                    {
                        //如果下一个是常数
                        if (i + 1 < valList.Count
                            && valList[i + 1].OpeType == OpeType.noParameter)
                        {
                            Insert(opeList.GetOpe(")"), i + 2);
                            Insert(opeList.GetOpe("("), i);
                            i++;
                        }
                    }
                }
            }
            #endregion

            #region 第二次处理
            //第二次处理,如sin30度,转换为sin(30度)
            for (int i = 0; i < valList.Count - 1; i++)
            {
                //如果是参数在右边的单目运算符
                if (valList[i].OpeType == OpeType.right
                    && valList[i].ParameterNumber == 1)
                {
                    //如果下一个是运算符且是左括号
                    if (valList[i + 1].OpeType == OpeType.leftParenthesis)
                    {
                        continue;
                    }

                    //如果下一个是常数或数字
                    if (valList[i + 1].OpeType == OpeType.noParameter
                        || valList[i + 1].type == ValType.Number)
                    {
                        //如果下下个运算符是参数在左边的运算符
                        if (i + 2 < valList.Count
                            && valList[i + 2].OpeType == OpeType.left)
                        {
                            Insert(opeList.GetOpe(")"), i + 3);
                            Insert(opeList.GetOpe("("), i + 1);
                            i++;
                        }
                        else
                        {
                            Insert(opeList.GetOpe(")"), i + 2);
                            Insert(opeList.GetOpe("("), i + 1);
                            i++;
                        }

                    }
                }
            }
            #endregion

            #region 第三次处理
            //第三次处理,如3+-3转换为3+(-3)
            for (int i = 1; i < valList.Count - 1; i++)
            {
                //如果是'+'或'-'运算符
                if (valList[i].OpeType == OpeType.PlusOrMinus)
                {
                    //如果前一个是运算符且类型如下
                    if (valList[i - 1].OpeType == OpeType.PlusOrMinus
                        || valList[i - 1].OpeType == OpeType.bothSides
                        || valList[i - 1].OpeType == OpeType.right)
                    {
                        //如果下一个是数字或常数
                        if (valList[i + 1].type == ValType.Number
                            || valList[i + 1].OpeType == OpeType.noParameter)
                        {
                            Insert(opeList.GetOpe(")"), i + 2);
                            Insert(opeList.GetOpe("("), i);
                            i++;
                        }
                    }
                }
            }
            #endregion

            #region 第四次处理
            //第四次处理,判断表达式是否合法,并在合适的地方插入乘号
            for (int i = 0; i < valList.Count - 1; i++)
            {
                #region 当前运算因子是数字
                if (valList[i].type == ValType.Number)//数字
                {
                    if (valList[i + 1].type == ValType.Operator)//右边是运算符
                    {
                        switch (valList[i + 1].OpeType)
                        {
                            case OpeType.bothSides://正确
                                break;
                            case OpeType.left://正确
                                break;
                            case OpeType.leftParenthesis:
                                Insert(opeList.GetOpe("*"), i + 1);
                                break;
                            case OpeType.noParameter:
                                Insert(opeList.GetOpe("*"), i + 1);
                                break;
                            case OpeType.PlusOrMinus://正确
                                break;
                            case OpeType.right:
                                Insert(opeList.GetOpe("*"), i + 1);
                                break;
                            case OpeType.rightParenthesis://正确
                                break;
                            case OpeType.Separator://正确
                                break;
                        }
                    }
                    else//右边是数字
                    {
                        Insert(opeList.GetOpe("*"), i + 1);
                    }
                }
                #endregion

                #region 当前运算因子是运算符
                if (valList[i].type == ValType.Operator)//运算符
                {
                    #region 当前运算符右边是运算符
                    if (valList[i + 1].type == ValType.Operator)//右边是运算符
                    {
                        switch (valList[i].OpeType)//左运算符
                        {
                            #region case OpeType.bothSides://左运算符参数信息
                            case OpeType.bothSides://左运算符参数信息
                                switch (valList[i + 1].OpeType)//右运算符
                                {
                                    case OpeType.bothSides:
                                        MakeException(i);
                                        break;
                                    case OpeType.left:
                                        MakeException(i);
                                        break;
                                    case OpeType.leftParenthesis://正确
                                        break;
                                    case OpeType.noParameter://正确
                                        break;
                                    case OpeType.PlusOrMinus:
                                        MakeException(i);
                                        break;
                                    case OpeType.right://正确
                                        break;
                                    case OpeType.rightParenthesis:
                                        MakeException(i);
                                        break;
                                    case OpeType.Separator:
                                        MakeException(i);
                                        break;
                                }
                                break;
                            #endregion

                            #region case OpeType.left://左运算符参数信息
                            case OpeType.left://左运算符参数信息
                                switch (valList[i + 1].OpeType)//右运算符
                                {
                                    case OpeType.bothSides://正确
                                        break;
                                    case OpeType.left://正确
                                        break;
                                    case OpeType.leftParenthesis:
                                        Insert(opeList.GetOpe("*"), i + 1);
                                        break;
                                    case OpeType.noParameter:
                                        Insert(opeList.GetOpe("*"), i + 1);
                                        break;
                                    case OpeType.PlusOrMinus://正确
                                        break;
                                    case OpeType.right:
                                        Insert(opeList.GetOpe("*"), i + 1);
                                        break;
                                    case OpeType.rightParenthesis://正确
                                        break;
                                    case OpeType.Separator: //正确
                                        break;
                                }
                                break;
                            #endregion

                            #region case OpeType.leftParenthesis://左运算符参数信息
                            case OpeType.leftParenthesis://左运算符参数信息
                                switch (valList[i + 1].OpeType)//右运算符
                                {
                                    case OpeType.bothSides:
                                        int pos = i + 1 >= 0 ? i + 1 : i;
                                        MakeException(pos);
                                        break;
                                    case OpeType.left:
                                        pos = i + 1 >= 0 ? i + 1 : i;
                                        MakeException(pos);
                                        break;
                                    case OpeType.leftParenthesis://正确
                                        break;
                                    case OpeType.noParameter://正确
                                        break;
                                    case OpeType.PlusOrMinus://正确
                                        break;
                                    case OpeType.right://正确
                                        break;
                                    case OpeType.rightParenthesis:
                                        pos = i - 1 >= 0 ? i - 1 : i;
                                        MakeException(pos);
                                        break;
                                    case OpeType.Separator:
                                        pos = i - 1 >= 0 ? i - 1 : i;
                                        MakeException(pos);
                                        break;
                                }
                                break;
                            #endregion

                            #region case OpeType.noParameter://左运算符参数信息
                            case OpeType.noParameter://左运算符参数信息
                                switch (valList[i + 1].OpeType)//右运算符
                                {
                                    case OpeType.bothSides://正确
                                        break;
                                    case OpeType.left://正确
                                        break;
                                    case OpeType.leftParenthesis:
                                        Insert(opeList.GetOpe("*"), i + 1);
                                        break;
                                    case OpeType.noParameter:
                                        Insert(opeList.GetOpe("*"), i + 1);
                                        break;
                                    case OpeType.PlusOrMinus://正确
                                        break;
                                    case OpeType.right:
                                        Insert(opeList.GetOpe("*"), i + 1);
                                        break;
                                    case OpeType.rightParenthesis://正确
                                        break;
                                    case OpeType.Separator: //正确
                                        break;
                                }
                                break;
                            #endregion

                            #region case OpeType.PlusOrMinus://左运算符参数信息
                            case OpeType.PlusOrMinus://左运算符参数信息
                                switch (valList[i + 1].OpeType)//右运算符
                                {
                                    case OpeType.bothSides:
                                        MakeException(i);
                                        break;
                                    case OpeType.left:
                                        MakeException(i);
                                        break;
                                    case OpeType.leftParenthesis://正确
                                        break;
                                    case OpeType.noParameter://正确
                                        break;
                                    case OpeType.PlusOrMinus:
                                        MakeException(i);
                                        break;
                                    case OpeType.right://正确
                                        break;
                                    case OpeType.rightParenthesis:
                                        MakeException(i);
                                        break;
                                    case OpeType.Separator:
                                        MakeException(i);
                                        break;
                                }
                                break;
                            #endregion

                            #region case OpeType.right://左运算符参数信息
                            case OpeType.right://左运算符参数信息
                                switch (valList[i + 1].OpeType)//右运算符
                                {
                                    case OpeType.bothSides:
                                        MakeException(i);
                                        break;
                                    case OpeType.left:
                                        MakeException(i);
                                        break;
                                    case OpeType.leftParenthesis://正确
                                        break;
                                    case OpeType.noParameter:
                                        MakeException(i);
                                        break;
                                    case OpeType.PlusOrMinus:
                                        MakeException(i);
                                        break;
                                    case OpeType.right:
                                        MakeException(i);
                                        break;
                                    case OpeType.rightParenthesis:
                                        MakeException(i);
                                        break;
                                    case OpeType.Separator:
                                        MakeException(i);
                                        break;
                                }
                                break;
                            #endregion

                            #region case OpeType.rightParenthesis://左运算符参数信息
                            case OpeType.rightParenthesis://左运算符参数信息
                                switch (valList[i + 1].OpeType)//右运算符
                                {
                                    case OpeType.bothSides://正确
                                        break;
                                    case OpeType.left://正确
                                        break;
                                    case OpeType.leftParenthesis:
                                        Insert(opeList.GetOpe("*"), i + 1);
                                        break;
                                    case OpeType.noParameter:
                                        Insert(opeList.GetOpe("*"), i + 1);
                                        break;
                                    case OpeType.PlusOrMinus://正确
                                        break;
                                    case OpeType.right:
                                        Insert(opeList.GetOpe("*"), i + 1);
                                        break;
                                    case OpeType.rightParenthesis://正确
                                        break;
                                    case OpeType.Separator://正确
                                        break;
                                }
                                break;
                            #endregion

                            #region case OpeType.Separator://左运算符参数信息
                            case OpeType.Separator://左运算符参数信息
                                switch (valList[i + 1].OpeType)//右运算符
                                {
                                    case OpeType.bothSides:
                                        MakeException(i + 1);
                                        break;
                                    case OpeType.left:
                                        MakeException(i + 1);
                                        break;
                                    case OpeType.leftParenthesis://正确
                                        break;
                                    case OpeType.noParameter://正确
                                        break;
                                    case OpeType.PlusOrMinus://正确
                                        break;
                                    case OpeType.right://正确
                                        break;
                                    case OpeType.rightParenthesis:
                                        MakeException(i);
                                        break;
                                    case OpeType.Separator:
                                        MakeException(i);
                                        break;
                                }
                                break;
                            #endregion

                        }
                    }
                    #endregion

                    #region 当前运算符右边是数字
                    else if (valList[i + 1].type == ValType.Number)//运算符右边是数字
                    {
                        switch (valList[i].OpeType)
                        {
                            case OpeType.bothSides://正确
                                break;
                            case OpeType.left:
                                Insert(opeList.GetOpe("*"), i + 1);
                                break;
                            case OpeType.leftParenthesis://正确
                                break;
                            case OpeType.noParameter:
                                Insert(opeList.GetOpe("*"), i + 1);
                                break;
                            case OpeType.PlusOrMinus://正确
                                break;
                            case OpeType.right:
                                MakeException(i);
                                break;
                            case OpeType.rightParenthesis:
                                Insert(opeList.GetOpe("*"), i + 1);
                                break;
                            case OpeType.Separator: //正确
                                break;
                        }
                    }
                    #endregion

                }
                #endregion

            }
            #endregion

            #region 第五次处理
            //检查表达式的开头和结尾(第四次处理检查不到的地方)、数字两边括号
            //*9不合法
            //8-不合法
            //nCr(9,8,7)不合法
            //(9)%处理成9%
            for (int i = 0; i < valList.Count; i++)//逐个扫描
            {
                #region 如果是运算符
                if (valList[i].type == ValType.Operator)//如果是运算符
                {
                    switch (valList[i].OpeType)
                    {
                        case OpeType.bothSides:
                            if (!(i - 1 >= 0 && i + 1 < valList.Count))
                            {
                                MakeException(i);
                            }
                            break;
                        case OpeType.left:
                            if (!(i - 1 >= 0))
                            {
                                MakeException(i);
                            }
                            break;
                        case OpeType.leftParenthesis:
                            if (!(i + 1 < valList.Count))
                            {
                                MakeException(i);
                            }
                            break;
                        case OpeType.noParameter:
                            break;
                        case OpeType.PlusOrMinus:
                            if (!(i + 1 < valList.Count))
                            {
                                MakeException(i);
                            }
                            break;
                        case OpeType.right:
                            if (!(i + 1 < valList.Count))
                            {
                                MakeException(i);
                            }
                            break;
                        case OpeType.rightParenthesis:
                            if (!(i - 1 >= 0))
                            {
                                MakeException(i);
                            }
                            break;
                        case OpeType.Separator:
                            if (!(i - 1 >= 0 && i + 1 < valList.Count))
                            {
                                MakeException(i);
                            }
                            break;
                    }
                }
                #endregion

                #region 如果是数字
                if (valList[i].type == ValType.Number)//如果是数字
                {
                    if (i - 1 >= 0 && i + 1 < valList.Count)
                    {
                        //两边同时为括号
                        if (valList[i - 1].OpeType == OpeType.leftParenthesis
                            && valList[i + 1].OpeType == OpeType.rightParenthesis)
                        {
                            //如sin(9-7),average(9-7)
                            if (!(i - 2 >= 0
                                && valList[i - 2].OpeType == OpeType.right))
                            {
                                ReplaceVal(valList[i].num, 3, i - 1);
                            }
                        }
                    }
                }
                #endregion

            }
            #endregion
        }
Beispiel #2
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;
        }
Beispiel #3
0
        /// <summary>
        /// 输入运算符
        /// </summary>
        /// <param name="sender"></param>
        private void InputOpe(object sender)
        {
            string[] tagList = ((Control)sender).Tag.ToString().Split('|');

            //输入运算符
            if (tagList[0] != "")
            {
                string str = tagList[0];

                //对于函数,输入左括号
                CalOpeList opeList = new CalOpeList();
                if (opeList.GetOpe(((Control)sender).Tag.ToString()) != null
                    && opeList.GetOpe(((Control)sender).Tag.ToString()).opeType == OpeType.right)
                {
                    str += "(";
                }

                //输入运算符
                Input(str);
            }
        }
Beispiel #4
0
        /// <summary>
        /// 是否负号
        /// </summary>
        /// <param name="strExp">已输入的表达式</param>
        /// <param name="tag">当前符号</param>
        public static bool isSubtractive(string strExp, string tag, int selectionStart)
        {
            bool result = false;//默认不是负号

            if (tag == "-")
            {
                strExp = strExp.Substring(0, selectionStart).Replace(" ", "");
                if (strExp.Length == 1)//只有一个符号
                {
                    result = true;
                }
                else
                {
                    //科学计数法的情况
                    if (strExp[strExp.Length - 2] == 'E')
                    {
                        result = true;
                    }
                    //前面是'='号的情况
                    if (strExp[strExp.Length - 2] == '=')
                    {
                        result = true;
                    }

                    CalOpeList opeList = new CalOpeList();
                    CalOpe ope = null;
                    //检测tag前面有没有运算符
                    for (int i = 0; i < strExp.Length; i++)
                    {
                        //从长字符串到短字符串检测
                        string subStr = strExp.Substring(i, strExp.Length - i - 1);
                        ope = opeList.GetOpe(subStr);//查找运算符
                        if (ope != null)//找到运算符
                        {
                            break;
                        }
                    }

                    if (ope != null)//找到运算符
                    {
                        //检测运算符种类
                        if (ope.opeType == OpeType.bothSides
                            || ope.opeType == OpeType.leftParenthesis
                            || ope.opeType == OpeType.PlusOrMinus
                            || ope.opeType == OpeType.right
                            || ope.opeType == OpeType.Separator)
                        {
                            result = true; ;
                        }
                    }
                }
            }

            return result;
        }