Пример #1
0
        // добавление потомков
        private void addChilds(BinaryTree tree, String sign, int pos)
        {
            String tmp = tree.getData();
            tree.setData(sign);
            BinaryTree left = new BinaryTree(); // добавление левого потомка
            left.setData(tmp.Substring(0, pos));
            tree.addLeftChild(left);

            BinaryTree right = new BinaryTree(); // добавление правого потомка
            right.setData(tmp.Substring(pos + 1));
            tree.addRightChild(right);
        }
Пример #2
0
        // нахождение всех ариф знаков во входной строке
        private List<SignPriority> findAllSignes(BinaryTree tree)
        {
            List<SignPriority> list = new List<SignPriority>();
            String function = tree.getData();
            int battery = 0;
            int someLength = function.Length - 2;
            for (int i = 0; i < someLength; i++)
            {
                if (function[i] == '(') // считаем кол-во скобочек
                    battery++;
                else if (function[i] == ')')
                    battery--;

                if (function[i] == '(' && i != 0) // скобка стоит не в начале,
                {
                    if (isSign(tree, i - 1))
                    {
                        if (battery == 0) // знак приоритетен
                            list.Add(new SignPriority(i - 1, function.Substring(i - 1, 1), true));
                        else // знак не приоритетен
                            list.Add(new SignPriority(i - 1, function.Substring(i - 1, 1), false));
                    }
                }
                else if (function[i] == ')' && function[i + 2] == '(' && isSign(tree, i + 1) && battery == 0) // добавление приоритетного знака между скобками
                {
                    list.Add(new SignPriority(i + 1, function.Substring(i + 1, 1), true));
                    i += 2;
                    battery++;
                }
                else if (function[i] == ')' && i != function.Length - 1 && isSign(tree, i + 1)) // добавление знака, стоящего после )
                {
                    if (battery == 0)
                        list.Add(new SignPriority(i + 1, function.Substring(i + 1, 1), true));
                    else
                        list.Add(new SignPriority(i + 1, function.Substring(i + 1, 1), false));
                    i++;
                }
                else if (isSign(tree, i) && battery == 0)
                    list.Add(new SignPriority(i, function.Substring(i, 1), true));
            }
            if (someLength > 0 && isSign(tree, someLength) && battery == 0) // для случая x+2
                list.Add(new SignPriority(someLength, function.Substring(someLength, 1), true));
            return list;
        }
Пример #3
0
 // удаление скобочек
 private void deleteBrackets(BinaryTree tree, String sign)
 {
     StringBuilder tmp = new StringBuilder(tree.getData());
     if (sign.Equals("("))
         tmp = tmp.Remove(tree.getData().IndexOf("("), 1);
     else if (sign.Equals(")"))
         tmp = tmp.Remove(tree.getData().LastIndexOf(")"), 1);
     tree.setData(tmp.ToString());
 }
Пример #4
0
 // упрощение функции
 private void simplifyFunction(BinaryTree tree)
 {
     String function = tree.getData();
     bool check = false;
     int battery = 0;
     int pos = 0;
     List<SignPriority> list = findAllSignes(tree); // находим все знаки
     //System.out.println(list);
     SignPriority sp = sort(tree, list); // сортируем их
     if (sp != null)
     { // если есть приоритеный знак
         pos = sp.getPos();
         for (int i = 0; i < pos; i++) // считаем кол-во скобочек
         {
             if (function[i] == '(') battery++;
             else if (function[i] == ')') battery--;
         }
         if (pos != -1)
         {
             for (int i = pos; i < function.Length; i++)
             {
                 if (isSign(tree, i))
                     check = true;
             }
         }
         else
         {
             for (int i = 0; i < function.Length; i++)
             {
                 if (function[i] == '(') battery++;
                 else if (function[i] == ')') battery--;
             }
             if (battery > 0) deleteBrackets(tree, "(");
             else if (battery < 0) deleteBrackets(tree, ")");
             return;
         }
     }
     if (battery > 0 && !check)
     {
         deleteBrackets(tree, "(");
         deleteBrackets(tree, ")");
     }
 }
Пример #5
0
        // добавляет нули вместо пустой строки в дереве разбора
        private void setZero(BinaryTree tree)
        {
            if (tree.getLeft()  != null)  setZero(tree.getLeft());
            if (tree.getRight() != null) setZero(tree.getRight());

            if (tree.getData().Equals(""))
                tree.setData("0");
        }
Пример #6
0
 // добавление к дереву триг функции
 private void parseTrigFunction(BinaryTree tree, int pos)
 {
     String tmp = tree.getData();
     BinaryTree left = new BinaryTree();
     tree.setData(tmp.Substring(pos, 3)); // триг функцию добавляем в вершину
     left.setData(tmp.Substring(pos + 3)); // а аргумент в левого потомка
     tree.addLeftChild(left);
     parse(tree.getLeft()); // парсим левого потомка
 }
Пример #7
0
 // регулярное выражение, определяющее является ли строка мат. знаком
 private bool isSign(BinaryTree tree, int pos)
 {
     string function = tree.getData();
     if (function[pos] == '+' || function[pos] == '-' || function[pos] == '*' ||
             function[pos] == '/' || function[pos] == '^')
         return true;
     return false;
 }
Пример #8
0
        // основной метод разбора дерева
        private void parse(BinaryTree tree)
        {
            bool findCos = tree.getData().Contains("cos"); // ищем тригонометрические функции
            bool findSin = tree.getData().Contains("sin");
            bool findLog = tree.getData().Contains("log");
            bool findExp = tree.getData().Contains("exp");

            int posOpenBracket = tree.getData().IndexOf("("); // ищем позиции ( и )
            int posCloseBracket = tree.getData().IndexOf(")");

            if ((findCos || findSin || findLog || findExp) &&
                    posOpenBracket != -1 && posCloseBracket != -1)
            {
                // это функция, содержащаю тригонометрические функции
                parseMathFunction(tree);
            }
            else if (posOpenBracket != -1 && posCloseBracket == -1)
            {
                // удаляем (
                deleteBrackets(tree, "(");
                parse(tree);
            }
            else if (posOpenBracket == -1 && posCloseBracket != -1)
            {
                // удаляем )
                deleteBrackets(tree, ")");
                parse(tree);
            }
            else if (posOpenBracket != -1 && posCloseBracket != -1)
            {
                // это функци со скобками
                simplifyFunction(tree); // упрощаем его
                List<SignPriority> list = findAllSignes(tree); // находим все знаки
                SignPriority sp = sort(tree, list); // сортируем по знакам
                if (list.Count == 0 && sp == null) // если нет знаков, то во входной функции лишние скобки
                {
                    deleteBrackets(tree, "("); // удаляем их
                    deleteBrackets(tree, ")");
                    parse(tree); // продолжаем парсить входную строку
                }
                else
                {
                    string sign = sp.getSign(); // получаем самый приоритетный знак
                    int pos = sp.getPos(); // получаем его позицию во входной строке
                    parseNext(tree, sign, pos);
                }
            }
            else if (posOpenBracket == -1 && posCloseBracket == -1)
            {
                // это функция без скобок
                if (CountMinus > 1) // если минусов больше, чем 1, то самый приоритетный знак - минус
                {
                    findMathSign(tree, "-");
                    findMathSign(tree, "+");
                    findMathSign(tree, "*");
                    findMathSign(tree, "/");
                    findMathSign(tree, "^");
                }
                else
                {
                    findMathSign(tree, "+");
                    findMathSign(tree, "-");
                    findMathSign(tree, "*");
                    findMathSign(tree, "/");
                    findMathSign(tree, "^");
                }
            }
        }
Пример #9
0
 // нахождение позиции тригонометрической функции
 private int findPosMathFunction(BinaryTree tree)
 {
     int posLog = tree.getData().IndexOf("log");
     int posCos = tree.getData().IndexOf("cos");
     int posSin = tree.getData().IndexOf("sin");
     int posExp = tree.getData().IndexOf("exp");
     if (posLog == 0)
         return posLog;
     else if (posCos == 0)
         return posCos;
     else if (posSin == 0)
         return posSin;
     else if (posExp == 0)
         return posExp;
     return -1;
 }
Пример #10
0
 // поиск мат знака
 private void findMathSign(BinaryTree tree, String sign)
 {
     int pos = 0;
     if (tree != null)
     {
         if (tree.getLeft() == null && tree.getRight() == null)
         {
             if (sign.Equals("-") && CountMinus > 1) // если - и их больше 1
             {
                 pos = tree.getData().LastIndexOf(sign);
                 CountMinus--;
             }
             else
                 pos = tree.getData().IndexOf(sign);
             if (pos != -1 && !isVariable(tree.getData()) && !isDigit(tree.getData()))
                 parseNext(tree, sign, pos);
         }
         else if (tree.getLeft() != null && tree.getRight() != null)
         {
             findMathSign(tree.getLeft(), sign);
             findMathSign(tree.getRight(), sign);
         }
         else
             throw new Exception("Ошибка при построении дерева!");
     }
 }
Пример #11
0
 // вычисление узла дерева
 private Double calculate(BinaryTree tree, List<double> args)
 {
     double tmp = 0;
     if (isSign(tree.getData())) // если это знак
     {
         tmp = calculateTree(tree, args); // то вычисляем поддерево
     }
     else if (isVariable(tree.getData())) // если переменная, то заменяем ее на соответствущее ей входное значение
     {
         for (int i = 0; i < var.Count; i++)
         {
             if (var[i].Equals(tree.getData()))
             {
                 tmp = args[i];
                 break;
             }
         }
     }
     else if (isDigit(tree.getData())) // если число, то парсим его
     {
         tmp = double.Parse(tree.getData());
     }
     return tmp;
 }
Пример #12
0
        // подсчет кол-ва переменных в дереве
        private void getCountVariables(BinaryTree tree)
        {
            if (tree.getLeft() != null) getCountVariables(tree.getLeft());
            if (tree.getRight() != null) getCountVariables(tree.getRight());

            if (isVariable(tree.getData()) && !isMathFunction(tree.getData()))
            {
                for (int i = 0; i < var.Count; i++)
                {
                    if (var[i].Equals(tree.getData())) // если такая переменная уже была посчитана
                    {
                        return;
                    }
                }
                var.Add(tree.getData()); // иначе добавляем ее
            }
        }
Пример #13
0
 // вычисление дерева
 private double calculateTree(BinaryTree tree, List<double> args)
 {
     double left = 0, right = 0, res = 0;
     if (tree.getData().Equals("+"))
     {
         left = calculate(tree.getLeft(), args); // считаем левую часть
         right = calculate(tree.getRight(), args); // считаем правую часть
         res = left + right;
     }
     else if (tree.getData().Equals("-"))
     {
         left = calculate(tree.getLeft(), args); // считаем левую часть
         right = calculate(tree.getRight(), args); // считаем правую часть
         res = left - right;
     }
     else if (tree.getData().Equals("*"))
     {
         left = calculate(tree.getLeft(), args); // считаем левую часть
         right = calculate(tree.getRight(), args); // считаем правую часть
         res = left * right;
     }
     else if (tree.getData().Equals("/"))
     {
         left = calculate(tree.getLeft(), args); // считаем левую часть
         right = calculate(tree.getRight(), args); // считаем правую часть
         res = left / right;
     }
     else if (tree.getData().Equals("^"))
     {
         left = calculate(tree.getLeft(), args); // считаем левую часть
         right = calculate(tree.getRight(), args); // считаем правую часть
         res = Math.Pow(left, right);
     }
     else if (tree.getData().Equals("cos"))
     {
         left = calculate(tree.getLeft(), args); // считаем левую часть
         res = Math.Cos(left);
     }
     else if (tree.getData().Equals("sin"))
     {
         left = calculate(tree.getLeft(), args); // считаем левую часть
         res = Math.Sin(left);
     }
     else if (tree.getData().Equals("exp"))
     {
         left = calculate(tree.getLeft(), args); // считаем левую часть
         res = Math.Exp(left);
     }
     else if (tree.getData().Equals("log"))
     {
         left = calculate(tree.getLeft(), args); // считаем левую часть
         res = Math.Log(left);
     }
     return res;
 }