//pruchod doleva private string ExecuteTreeLeft(Nodes list) { if (list.left == null) { return(list.Value); } return(TreeCalculation.ExecuteOperation(ExecuteTreeLeft(list.left), ExecuteTreeRight(list.right), list.Value)); }
private void ExecuteTree() { this.result = TreeCalculation.ExecuteOperation(ExecuteTreeLeft(this.root.left), ExecuteTreeRight(this.root.right), this.root.Value); }
// projede string a vytvori strom private void ParseString(string input) { if (input[0] == '(' && input[input.Length - 1] == ')') { input = input.Remove(0, 1); input = input.Remove(input.Length - 1, 1); } // sekce hlavniho rozparsovani List <StringBuilder> parsing = new List <StringBuilder>(); bool pismeno = false; bool cislo = false; bool key_word = false; bool must_znamenko = false; int count_argument = 0; int parsing_counter = 0; // udava aktualni zapisovaci polozku v seznamu int cout_bracket = 0; //celkovy pocet zavorek int cout_priority = 0; //udava celkovy pocet prioritnich operaci int cout_operation = 0; // udava celkovy pocet operaci #region Rozparsování na jednotlivé části // rozparsovani input na jednotlive sekce for (int i = 0; i < input.Length; i++) { if (parsing_counter >= parsing.Count) { parsing.Add(new StringBuilder()); } if (char.IsLetter(input[i])) { // pokud narazi na pismeno, nastavi pismeno na true a zapise do aktualniho parsing pismeno = true; parsing[parsing_counter].Append(input[i]); } else if (char.IsWhiteSpace(input[i])) { // pokud narazi na mezeru overi, zda predtim nezapisoval cisla ci pismena // pokud zapisoval cisla ukonci zapis cisel a prejde na dalsi parsing (parsing_counter++) // pokud zapisoval pismena, overi, zda zapsana promenna neni registrovane klicove slovo // pokud ano zjisti pocet argumentu a podle toho pokracuje if (cislo) { if (key_word) { if (--count_argument > 0) { parsing[parsing_counter].Append(" "); cislo = false; continue; } else { must_znamenko = true; key_word = false; cislo = false; parsing_counter++; } } else { cislo = false; parsing_counter++; must_znamenko = true; } } else if (pismeno) { pismeno = false; // porovnani s klicovymi slovy /*for (int ii = 0; ii < Tree.KeyWord.Length; ii++) * { * if (Tree.KeyWord[ii] == parsing[parsing_counter].ToString()) * { * // vrati pocet argumentu * key_word = true; * count_argument = Function.GetCountArgument(parsing[parsing_counter].ToString()); * parsing[parsing_counter].Append(" "); * break; * } * if (ii == Tree.KeyWord.Length - 1) * { * parsing_counter++; * pismeno = false; * must_znamenko = true; * break; * } * * * }*/ Regex kwords = new Regex(Tree.KeyWord[0]); if (kwords.IsMatch(parsing[parsing_counter].ToString())) { // vrati pocet argumentu key_word = true; count_argument = Function.GetCountArgument(parsing[parsing_counter].ToString()); parsing[parsing_counter].Append(" "); continue; } else { parsing_counter++; pismeno = false; must_znamenko = true; continue; } } } else if (char.IsNumber(input[i]) || input[i] == '.' || input[i] == '^') { if (key_word) { if (!cislo) { count_argument--; } } cislo = true; parsing[parsing_counter].Append(input[i]); } else if (input[i] == '+' || input[i] == '-' || input[i] == '/' || input[i] == '*') // || input[i] == '(') { cout_operation++; // inkrementuje celkovy pocet operaci if (input[i] == '/' || input[i] == '*') // pokud je to jedno z prioritnich znaminek { cout_priority++; } must_znamenko = false; cislo = false; pismeno = false; if (parsing[parsing_counter].Length > 0) { parsing.Add(new StringBuilder()); parsing[++parsing_counter].Append(input[i]); parsing_counter++; } else { parsing[parsing_counter++].Append(input[i]); } } /*else if (input[i] == ')') * { * if (parsing[parsing_counter].Length > 0) * { * parsing.Add(new StringBuilder()); * parsing[++parsing_counter].Append(input[i]); * parsing_counter++; * } * else * parsing[parsing_counter++].Append(input[i]); * }*/ else if (input[i] == '(') { int zavorka = 0; cout_bracket++; parsing.Add(new StringBuilder()); for (int ii = i; ii < input.Length; ii++) { parsing[parsing_counter].Append(input[ii]); if (input[ii] == '(') { zavorka++; } if (input[ii] == ')') { if (--zavorka == 0) { i = ii; break; } } } parsing_counter++; } } #endregion if (parsing[parsing.Count - 1].Length == 0) { parsing.Remove(parsing[parsing.Count - 1]); } // druhy pruchod rozdeleni do stromu //bool zavorka = false; //provedeme spocitani jednotlivych zavorek if (cout_bracket > 0) { for (int i = 0; i < parsing.Count; i++) { if (parsing[i][0] == '(') { Tree bracket_calculation = new Tree(parsing[i].ToString()); parsing[i] = new StringBuilder(bracket_calculation.GetResult()); if (--cout_bracket == 0) { break; } } } } // pokud je pocet prioritnich operaci nula, neni treba tvorit strom // a nebo pokud jsou vsecny operace prioritni neni potreba tvori strom if (cout_priority == 0 || cout_priority == cout_operation) { string res = parsing[0].ToString(); //string op1 = parsing[0].ToString(); string op2 = ""; string zn = ""; for (int i = 1; i < parsing.Count; i++) { if (parsing[i].ToString() == "+" || parsing[i].ToString() == "-" || parsing[i].ToString() == "*" || parsing[i].ToString() == "/") { // pokud se rovna "" tak znamenko jeste nebylo prirazeno a priradi // pokud ne, tak uz je u dalsiho znamenka a provede vypocet if (zn == "") { zn = parsing[i].ToString(); } else { i--; // vrati, protoze pri dalsim inkrementu by znamenko vynechal res = TreeCalculation.ExecuteOperation(res, op2, zn); zn = ""; } } else { op2 = parsing[i].ToString(); } } res = TreeCalculation.ExecuteOperation(res, op2, zn); this.result = res; return; } // this.CreateFirst(parsing.ToArray()); // vytvori zaklad stromu #region Rozdělení do stromu for (int i = 0; i < parsing.Count; i++) { Nodes buff = new Nodes(GetNameNode(parsing[i].ToString()), parsing[i].ToString()); if (IsValue(parsing[i].ToString())) { if (i + 1 >= parsing.Count) { //if (IsPlusMinus(parsing[i - 1]) && !IsPlusMinus(parsing[i - 3])) break; } if (IsPlusMinus(parsing[i + 1].ToString())) { if (root != null) // pokud byl uz root vytvoren jen ho presune { Nodes old_root = this.root; if (this.root.right != null) { this.root.left = new Nodes(GetNameNode(parsing[i].ToString()), parsing[i].ToString()); } else { this.root.right = new Nodes(GetNameNode(parsing[i].ToString()), parsing[i].ToString()); } this.root = new Nodes(GetNameNode(parsing[++i].ToString()), parsing[i].ToString()); // pokud koren obsahuje * tak je prirazen v pravo if (!IsPlusMinus(old_root.Value)) { this.root.right = old_root; } else { this.root.left = old_root; } } else // pokud nebyl tak se podiva na dalsi znamenko, pokud je plus priradi hodnotu na prave, pokud je * tak inkrementuje a pokracuje { this.root = new Nodes(GetNameNode(parsing[++i].ToString()), parsing[i].ToString()); this.root.left = buff; if (i + 2 >= parsing.Count || IsPlusMinus(parsing[i + 2].ToString())) { Nodes old_root = root; this.root.right = new Nodes(GetNameNode(parsing[++i].ToString()), parsing[i++].ToString()); // prida na pravou stranu hodnotu /inkrementuje na znamenko this.root = new Nodes(GetNameNode(parsing[i].ToString()), parsing[i].ToString()); // a vytvori novy koren z nasledujiciho znamenka, pouze pokud je to plus ci minus this.root.left = old_root; } } } else { if (root != null) // pokud byl uz root vytvoren najde nejposlednejsi vetev a priradi se { i++; // inkrementuje se, aby odpovidal hodnote znamenka if (i + 2 >= parsing.Count || IsPlusMinus(parsing[i + 2].ToString())) // pokud je nasledujici znamenko +/- ulozi hodnotu i napravo { Nodes buf_right = this.root; // vyhledání posledniho predka napravo while (buf_right.right != null) { buf_right = buf_right.right; } Nodes buf2 = new Nodes(GetNameNode(parsing[i].ToString()), parsing[i].ToString()); buf_right.right = buf2; buf2.left = new Nodes(GetNameNode(parsing[i - 1].ToString()), parsing[i - 1].ToString()); buf2.right = new Nodes(GetNameNode(parsing[++i].ToString()), parsing[i++].ToString()); //inkrementace na uroven nasledujiciho znamenka // a je potreba pro hladky chod algoritmu vytvorit koren zde if (i >= parsing.Count) // kontrola parsovani { break; } buf_right = this.root; this.root = new Nodes(GetNameNode(parsing[i].ToString()), parsing[i].ToString()); this.root.left = buf_right; if (i + 2 == parsing.Count) { this.root.right = new Nodes(GetNameNode(parsing[++i].ToString()), parsing[i].ToString()); } } else // v ostatnich pripadech prida jen do prava { Nodes buf_right = this.root; // vyhledání posledniho predka napravo while (buf_right.right != null) { buf_right = buf_right.right; } Nodes buf2 = new Nodes(GetNameNode(parsing[i].ToString()), parsing[i].ToString()); buf_right.right = buf2; buf2.left = new Nodes(GetNameNode(parsing[i - 1].ToString()), parsing[i - 1].ToString()); } } else // pokud nebyl tak se podiva na dalsi znamenko, pokud je plus priradi hodnotu na prave, pokud je * tak inkrementuje a pokracuje { this.root = new Nodes(GetNameNode(parsing[++i].ToString()), parsing[i].ToString()); this.root.left = buff; if (i + 2 >= parsing.Count || IsPlusMinus(parsing[i + 2].ToString())) { Nodes old_root = root; this.root.right = new Nodes(GetNameNode(parsing[++i].ToString()), parsing[i++].ToString()); // prida na pravou stranu hodnotu /inkrementuje na znamenko this.root = new Nodes(GetNameNode(parsing[i].ToString()), parsing[i].ToString()); // a vytvori novy koren z nasledujiciho znamenka, pouze pokud je to plus ci minus this.root.right = old_root; if (i + 2 == parsing.Count) { this.root.left = new Nodes(GetNameNode(parsing[++i].ToString()), parsing[i].ToString()); } } } } } } #endregion ExecuteTree(); }