Пример #1
0
        public string MidtoPosfix()
        {
            Stack <string> a           = new Stack <string>();
            string         ketQuaHauTo = "";
            string         tokken;
            string         nhap = textBox1.Text;

            nhap = nhap.Trim();
            string s = "";

            for (int i = 0; i < nhap.Length; i++)
            {
                if (nhap[i] != ' ')
                {
                    s += nhap[i];
                }
            }
            int demMoNgoac   = 0;
            int demDongNgoac = 0;
            int demToanTu    = 0;
            int demToanHang  = 0;

            for (int i = 0; i < s.Length;)
            {
                GetTokken(s, out tokken, ref i);
                if (tokken[0] == '(')
                {
                    demMoNgoac++;
                }
                else if (tokken[0] == ')')
                {
                    demDongNgoac++;
                }
                else if (LaToanTu(tokken[0]))
                {
                    demToanTu++;
                }
                else
                {
                    demToanHang++;
                }
            }
            if (demDongNgoac == demMoNgoac && demToanHang - 1 == demToanTu)
            {
                for (int i = 0; i < s.Length;)
                {
                    GetTokken(s, out tokken, ref i);
                    if (!LaToanTu(tokken[0]))
                    {
                        ketQuaHauTo += tokken + " ";
                    }
                    else
                    {
                        if (tokken[0] == '(')
                        {
                            a.Push(tokken);
                        }
                        else if (tokken[0] == ')')
                        {
                            while (a.Top()[0] != '(')
                            {
                                ketQuaHauTo += a.Top() + " ";
                                a.Pop();
                            }
                            if (a.Top()[0] == '(')
                            {
                                a.Pop();
                            }
                        }
                        else
                        {
                            if (!a.IsEmpty() && DoUuTien(a.Top()[0]) < DoUuTien(tokken[0]))
                            {
                                a.Push(tokken);
                                continue;
                            }
                            else if (a.IsEmpty())
                            {
                                a.Push(tokken);
                                continue;
                            }
                            while (!a.IsEmpty() && DoUuTien(a.Top()[0]) >= DoUuTien(tokken[0]))
                            {
                                ketQuaHauTo += a.Top() + " ";
                                a.Pop();
                            }
                            a.Push(tokken);
                        }
                    }
                }
                while (!a.IsEmpty())
                {
                    if (a.Top()[0] == '(')
                    {
                        a.Pop();
                        continue;
                    }
                    ketQuaHauTo += a.Top() + " ";
                    a.Pop();
                }
                return(ketQuaHauTo);
            }
            else
            {
                return("\nBieu thuc sai");
            }
        }
Пример #2
0
        //Vaildate方法 验证算式字符串是否合法
        public static bool Vaildate(string input)
        {
            bool   flag     = true;
            string ErrorMsg = string.Empty;

            //判断算式去除字母和空字符后是否为空
            if (input.Length == 0)
            {
                flag     = false;
                ErrorMsg = "Empty string";
                goto Tail;
            }

            //判断算式是否含有非法字符
            if (new Regex("[^0-9.*+/()#-]").IsMatch(input))
            {
                flag     = false;
                ErrorMsg = "Illegal character exists";
                goto Tail;
            }

            //判断算式末尾是否含有#号
            if (!input.EndsWith("#"))
            {
                flag     = false;
                ErrorMsg = "Miss a hashtag";
                goto Tail;
            }

            //判断括号是否配对
            Stack Brackets = new Stack();

            if (input.Contains(")(") || input.Contains("()"))
            {
                flag     = false;
                ErrorMsg = "Brackets not match";
                goto Tail;
            }
            foreach (char c in input)
            {
                if (c == '(')
                {
                    Brackets.Push(c.ToString());
                }
                else if (c == ')')
                {
                    if (Brackets.IsEmpty())
                    {
                        flag     = false;
                        ErrorMsg = "Brackets not match";
                        goto Tail;
                    }
                    else
                    {
                        Brackets.Pop();
                    }
                }
            }
            if (!Brackets.IsEmpty())
            {
                flag     = false;
                ErrorMsg = "Brackets not match";
                goto Tail;
            }

            //判断算是是否符合语法
            if (new Regex("^[.*+/-]").IsMatch(input) || new Regex("[.*+/-](?=#?$)").IsMatch(input) || new Regex("[*+/#()-]+[.]").IsMatch(input) || new Regex("[.][*+/#()-]+").IsMatch(input) || new Regex("[0-9]+[.][0-9]+[.][0-9]+").IsMatch(input) || new Regex("[.*+/#-]{2,}").IsMatch(input) || new Regex("[#].*[#]").IsMatch(input))
            {
                flag     = false;
                ErrorMsg = "Syntax error";
                goto Tail;
            }

Tail:
            if (!flag)
            {
                Console.WriteLine(ErrorMsg);
            }
            return(flag);
        }
Пример #3
0
        public string GetReverseNotation(string line, out Stack <Actions> actions, out Stack <string> operands)
        {
            string result = "";

            actions  = new Stack <Actions>();
            operands = new Stack <string>();

            Stack <Actions> functions = new Stack <Actions>();

            for (int i = 0; i < line.Length; i++)
            {
                if (IsSplite(line[i]))
                {
                    continue;
                }
                if (IsDigit(line[i]) && (i == 0 || line[i - 1] != '.'))
                {
                    AddDigits(ref result, line, ref i, operands);
                    continue;
                }

                if (line[i] == '(')
                {
                    functions.Push(new Actions("(", false, -1));
                    continue;
                }

                if (line[i] == ')')
                {
                    AddFunctionsAndOperations(functions, ref result, actions);
                    continue;
                }

                if (IsBinaryOperation(line, i))
                {
                    AddOperationToStack(functions, line, i, ref result, actions);
                    continue;
                }

                if (IsConstant(line, ref i, ref result, operands))
                {
                    continue;
                }

                AddFunctionToStack(functions, line, ref i);
            }

            while (!functions.IsEmpty())
            {
                if (!IsFunction(functions.Top().Name) && (functions.Top().Name.Length == 0 ||
                                                          functions.Top().Name[0] != '+' && functions.Top().Name[0] != '-' &&
                                                          functions.Top().Name[0] != '*' && functions.Top().Name[0] != '/' &&
                                                          functions.Top().Name[0] != '^'))
                {
                    throw new Exception("Строка не корректно задана");
                }
                result += functions.Top().Name;
                actions.Push(functions.Top());
                result += ' ';
                functions.Pop();
            }

            actions  = actions.ReverseStack();
            operands = operands.ReverseStack();

            return(result);
        }
Пример #4
0
 private bool IsUnaryOperation(string line, int index, Stack <Actions> functions)
 {
     return(index == 0 || IsBinaryOperation(line, index - 1) ||
            line[index - 1] == '(' ||
            !functions.IsEmpty() && functions.Top().IsFunction);
 }
Пример #5
0
        // 进行运算
        private double Calculate(string operators, string numbers) {
            // 将数字和操作符字符串存到数组当中
            string[] numberarray = Regex.Split(numbers, " ");
            string[] operatorarray = Regex.Split(operators, " ");
            Stack numberStack = new Stack();// 数字栈
            Stack operatorStack = new Stack();// 操作符栈

            // 先将前两个数字和一个操作符push到栈中
            numberStack.Push(Convert.ToDouble(numberarray[0]));
            numberStack.Push(Convert.ToDouble(numberarray[1]));
            operatorStack.Push(operatorarray[0]);
            
            // 当遍历完操作符数组且栈中操作符为空时跳出循环
            for (int i = 1; i < operatorarray.Length || !operatorStack.IsEmpty();) {
                // 当操作符栈为空时,push一个数字和一个操作符
                if (operatorStack.IsEmpty()) {
                    numberStack.Push(Convert.ToDouble(numberarray[i + 1]));
                    operatorStack.Push(operatorarray[i]);
                    i++;continue;
                }
                // 当栈顶操作符为+或者-时
                if (operatorStack.getTop().Equals("+") || operatorStack.getTop().Equals("-")) {
                    if (i < operatorarray.Length) { // 当下一个操作符不是最后一个操作符时
                        // 如果下一个操作符为*或者/,则push一个数字和操作符
                        if (operatorarray[i].Equals("*") || operatorarray[i].Equals("/")) {
                            numberStack.Push(Convert.ToDouble(numberarray[i + 1]));
                            operatorStack.Push(operatorarray[i]);
                            i++;
                        } else {// 否则,栈内进行加减运算,将结果push到栈顶,下同
                            double after = Convert.ToDouble(numberStack.Pop());
                            double pre = Convert.ToDouble(numberStack.Pop());
                            string op = operatorStack.Pop().ToString();
                            switch (op) {
                                case "+": { numberStack.Push(pre + after); continue; }
                                case "-": { numberStack.Push(pre - after); continue; }
                                default: continue;
                            }
                        }
                    } else {// 如果没有下一个操作符,则栈内进行加减运算
                        double after = Convert.ToDouble(numberStack.Pop());
                        double pre = Convert.ToDouble(numberStack.Pop());
                        string op = operatorStack.Pop().ToString();
                        switch (op) {
                            case "+": { numberStack.Push(pre + after); continue; }
                            case "-": { numberStack.Push(pre - after); continue; }
                            default: continue;
                        }
                    }
                } else {// 如果栈顶操作符为*或者/,则栈内直接进行乘除运算
                    double after = Convert.ToDouble(numberStack.Pop());
                    double pre = Convert.ToDouble(numberStack.Pop());
                    string op = operatorStack.Pop().ToString();
                    switch (op) {
                        case "*": { numberStack.Push(pre * after); continue; }
                        case "/": { numberStack.Push(pre / after); continue; }
                        default: continue;
                    }
                }
            }
            // 取出栈顶元素作为结果返回
            object result = numberStack.Pop();
            return Convert.ToDouble(result);
        }
Пример #6
0
        private List <String> infixToPostfix(char[] operand) //中缀表达式转换为后缀表达式
        {
            List <String> str1 = new List <string>();        //因数及运算符存储
            Stack <char>  s    = new Stack <char>();
            char          y    = '\0'; s.Push('#');          //#号作为结束的标志

            for (int i = 0; i < operand.Length; i++)
            {
                if (operand[i] >= '0' && operand[i] <= '9')
                {
                    double sum  = 0,     //运算符边的数字
                           sum1 = 0;     //运算符边的数字
                    int  n      = 0;
                    bool dot    = false; //判断是否有小数点
                    bool mod    = false; //判断是否有模运算
                    for (; i < operand.Length && (operand[i] >= '0' && operand[i] <= '9' || operand[i] == '.' || operand[i] == '!' || operand[i] == '%'); i++)
                    {
                        if (operand[i] == '.')//判断是否有小数点
                        {
                            dot = true;
                            continue;
                        }
                        if (operand[i] == '!')   //计算阶乘
                        {
                            if (!dot)
                            {
                                sum = factorial(sum);         //判断,小数没有阶乘
                            }
                            else
                            {
                                Form1.str = "错误";
                            }
                            continue;
                        }
                        if (operand[i] == '%')   //判断是否有模运算
                        {
                            mod  = true;
                            sum1 = sum;
                            sum  = 0;
                            continue;
                        }
                        if (!dot)
                        {
                            sum = sum * 10 + (operand[i] - '0'); //算整数
                        }
                        else                                     //加上小数
                        {
                            sum = sum + (operand[i] - '0') * Math.Pow(10, -++n);
                        }
                        if (mod)
                        {
                            if ((i + 1) < operand.Length && (operand[i + 1] >= '0' && operand[i + 1] <= '9' || operand[i + 1] == '.' || operand[i + 1] == '!' || operand[i + 1] == '%'))
                            {
                                ;
                            }
                            else if (sum >= 1)
                            {
                                sum = (int)sum1 % (int)sum;
                            }
                            else
                            {
                                Form1.str = "错误";
                            }
                        }
                    }
                    i--;      //把多增加的i减回来
                    str1.Add(sum.ToString());
                }
                else if (operand[i] == '√')     //求根号
                {
                    double sum = 0;
                    int    n   = 0;
                    bool   dot = false;
                    for (i++; i < operand.Length && (operand[i] >= '0' && operand[i] <= '9' || operand[i] == '.' || operand[i] == '!'); i++)
                    {
                        if (operand[i] == '.')//判断是否有小数点
                        {
                            dot = true;
                            continue;
                        }
                        if (operand[i] == '!')   //计算阶乘
                        {
                            if (!dot)
                            {
                                sum = factorial(sum);         //判断,小数没有阶乘
                            }
                            else
                            {
                                Form1.str = "错误";
                            }
                            continue;
                        }
                        if (!dot)
                        {
                            sum = sum * 10 + (operand[i] - '0'); //算整数
                        }
                        else                                     //加上小数
                        {
                            sum = sum + (operand[i] - '0') * Math.Pow(10, -++n);
                        }
                    }
                    sum = Math.Sqrt(sum); //求根号
                    i--;                  //把多增加的i减回来
                    str1.Add(sum.ToString());
                }
                else if (operand[i] == ')')
                {
                    for (s.Top(ref y), s.Pop(); y != '('; s.Top(ref y), s.Pop())
                    {
                        str1.Add(y.ToString());
                    }
                }
                else
                {
                    for (s.Top(ref y), s.Pop(); icp(operand[i]) <= isp(y); s.Top(ref y), s.Pop())
                    {
                        str1.Add(y.ToString());
                    }
                    s.Push(y);
                    s.Push(operand[i]);
                }
            }
            while (!s.IsEmpty())
            {
                s.Top(ref y);
                s.Pop();
                if (y != '#')
                {
                    str1.Add(y.ToString());
                }
            }
            return(str1);
        }