Facebook
From Chunky Echidna, 1 Year ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 203
  1. #pragma once
  2.  
  3. #include <iostream>
  4. #include <cmath>
  5. #include "Tree.h"
  6. #include "Node_function.h"
  7. #include "Node_variable.h"
  8. #include "Node_constant.h"
  9. #include "RETURN.h"
  10. #include "User.h"
  11.  
  12. #pragma once
  13. #include <iostream>
  14. #include <vector>
  15.  
  16. template <class T> class Node {
  17.         template <class T> friend class Tree;
  18.  
  19. public:
  20.         Node(int _children_quantity, std::string _alias);
  21.         virtual ~Node();
  22.  
  23.         virtual void set_args(T *_args) = 0;
  24.         virtual bool is_completed() const = 0;
  25.         virtual T get_value()  const = 0;
  26.  
  27.         int get_childrens_quantity() const;
  28.         std::string get_alias() const;
  29.  
  30. //protected:
  31.         int childrens_quantity;
  32.         std::string alias;
  33.         std::vector<Node<T>*> childrens;
  34. };
  35.  
  36. //--------------------------------------------------------
  37.  
  38. template <class T> Node<T>::Node(int _children_quantity, std::string _alias) :
  39.         childrens_quantity(_children_quantity),
  40.         alias(_alias) {
  41.  
  42. }
  43.  
  44. template <class T> Node<T>::~Node() {
  45.         std::cout << "Destroy: " + alias << '\n';
  46.         for (int i = 0; i < childrens.size(); i++) {
  47.                 delete childrens.at(i);
  48.         }
  49. }
  50.  
  51. template <class T> std::string Node<T>::get_alias() const {
  52.         return alias;
  53. }
  54.  
  55. template <class T> int Node<T>::get_childrens_quantity () const {
  56.         return childrens_quantity;
  57. }
  58.  
  59. #pragma once
  60. #include "Node.h"
  61.  
  62. template <class T> class Node_constant : public Node<T> {
  63.         template <class T> friend class Tree;
  64.  
  65. public:
  66.         Node_constant(std::string _alias, T _value);
  67.         ~Node_constant();
  68.  
  69.         void set_args(T *_args);
  70.         bool is_completed() const;
  71.         T get_value() const;
  72.  
  73. //private:
  74.         T value;
  75. };
  76.  
  77. //--------------------------------------------------------
  78.  
  79. template <class T> Node_constant<T>::Node_constant(std::string _alias, T _value) :
  80.         Node(0, _alias),
  81.         value(_value){
  82.  
  83. }
  84.  
  85. template <class T> Node_constant<T>::~Node_constant() {
  86.  
  87. }
  88.  
  89. template <class T> void Node_constant<T>::set_args(T *_args) {
  90.         value = *_args;
  91. }
  92.  
  93. template <class T> bool Node_constant<T>::is_completed() const {
  94.         return true;
  95. }
  96.  
  97. template <class T> T Node_constant<T>::get_value() const {
  98.         return value;
  99. }
  100.  
  101. #pragma once
  102. #include "Node.h"
  103.  
  104. template <class T> class Node_variable : public Node<T> {
  105.         template <class T> friend class Tree;
  106.  
  107. public:
  108.         Node_variable(std::string _alias);
  109.         ~Node_variable();
  110.  
  111.         void set_args(T *_args);
  112.         bool is_completed() const;
  113.         T get_value() const;
  114.  
  115. //private:
  116.         T value;
  117. };
  118.  
  119. //--------------------------------------------------------
  120.  
  121. template <class T> Node_variable<T>::Node_variable(std::string _alias) :
  122.         Node(0, _alias),
  123.         value(NULL) {
  124. }
  125.  
  126.  
  127. template <class T> Node_variable<T>::~Node_variable() {
  128.  
  129. }
  130.  
  131. template <class T> void Node_variable<T>::set_args(T *_args) {
  132.         value = *_args;
  133. }
  134.  
  135. template <class T> bool Node_variable<T>::is_completed() const {
  136.         return true;
  137. }
  138.  
  139. template <class T> T Node_variable<T>::get_value() const {
  140.         return value;
  141. }
  142.  
  143.  
  144. #pragma once
  145. #include "Node.h"
  146.  
  147. template <class T> class Node_function : public Node<T> {
  148.         template <class T> friend class Tree;
  149.  
  150. public:
  151.         Node_function(std::string _alias, int _args_quantity, T (*_function)(T *_args));
  152.         ~Node_function();
  153.  
  154.         void set_args(T *_args);
  155.         bool is_completed() const;
  156.         T get_value() const;
  157.  
  158. //private:
  159.         T *args;
  160.         T (*function)(T *args);
  161. };
  162.  
  163. //--------------------------------------------------------
  164.  
  165. template <class T> Node_function<T>::Node_function(std::string _alias, int _args_quantity, T(*_function)(T *_args)) :
  166.         Node(_args_quantity, _alias),
  167.         args(new T[_args_quantity]),
  168.         function(_function){
  169.  
  170. }
  171.  
  172. template <class T> Node_function<T>::~Node_function() {
  173.         delete args;
  174. }
  175.  
  176. template <class T> void Node_function<T>::set_args(T *_args) {
  177.         args = _args;
  178. }
  179.  
  180. template <class T> bool Node_function<T>::is_completed() const {
  181.         bool result = childrens_quantity == childrens.size();
  182.  
  183.         int i = 0;
  184.         while (i < childrens_quantity && result) {
  185.                 if (childrens.at(i) == nullptr) {
  186.                         result = false;
  187.                 } else {
  188.                         result = childrens.at(i)->is_completed();
  189.                 }
  190.                 i++;
  191.         }
  192.  
  193.         return result;
  194. }
  195.  
  196. template <class T> T Node_function<T>::get_value() const {
  197.         for (int i = 0; i < childrens.size(); i++) {
  198.                 args[i] = childrens.at(i)->get_value();
  199.         }
  200.  
  201.         return function(args);
  202. }
  203.  
  204. #pragma once
  205. #include <iostream>
  206. #include <string>
  207. #include <stack>
  208. #include <vector>
  209. #include <algorithm>
  210. #include <stdlib.h>
  211. #include <time.h>
  212. #include "Node_function.h"
  213. #include "Node_variable.h"
  214. #include "Node_constant.h"
  215. #include "RETURN.h"
  216.  
  217. template <class T> class Tree {
  218. public:
  219.         Tree();
  220.         ~Tree();
  221.  
  222.         RETURN<bool> add_function(std::string _alias, int _args_quantity, T (*_function)(T *_args));
  223.         RETURN<bool> add_variable(std::string _alias);
  224.         RETURN<bool> add_constant(T _value);
  225.         RETURN<bool> is_completed() const;
  226.  
  227.         RETURN<T> calculate(int _args_quantity, T *_args);
  228.  
  229.         RETURN<std::string> vars() const;
  230.         RETURN<std::string> print() const;
  231.  
  232.         Tree<T>& operator=(const Tree<T> &_other);
  233.         Tree<T>& operator+(const Tree<T> &_other) const;
  234.  
  235. //private:
  236.         void set_new(Node<T> *_begin, Node<T> *_new_node);
  237.         void preorder(Node<T> *_current) const;
  238.         std::vector<Node<T>*> get_variables() const;
  239.  
  240.         Node<T> *root;
  241. };
  242.  
  243. /**
  244. Create new Tree and set root as NULL
  245. */
  246. template <class T> Tree<T>::Tree() :
  247.         root(nullptr) {
  248. }
  249.  
  250. /**
  251. Delete Tree, nodes are being deleted in preorder
  252. */
  253. template <class T> Tree<T>::~Tree() {
  254.         std::cout << "delete: " << '\n';
  255.         delete root;
  256. }
  257.  
  258. /**
  259. Add new node containing function in first empty place found by preorder algorithm
  260.  
  261. @_alias Name of function
  262. @_args_quantity How many arguments function takes
  263. @_function Pointer to function to storage in node
  264. */
  265. template <class T> RETURN<bool> Tree<T>::add_function(std::string _alias, int _args_quantity, T(*_function)(T *_args)) {
  266.         RETURN<bool> _return;
  267.         if (_args_quantity < 0) {
  268.                 _return.set_return_code(error);
  269.                 _return.set_value(false);
  270.                 _return.set_message("Function cannot take negative amount of arguments");
  271.                 return _return;
  272.         }
  273.         if (_function == nullptr) {
  274.                 _return.set_return_code(error);
  275.                 _return.set_value(false);
  276.                 _return.set_message("Pointer to function cannto be null");
  277.                 return _return;
  278.         }
  279.  
  280.  
  281.         if (root != nullptr) {
  282.                 if (root->is_completed()) {
  283.                         _return.set_return_code(warning);
  284.                         _return.set_message("Tree is already complete");
  285.                         return _return;
  286.                 }
  287.  
  288.                 set_new(root, new Node_function<T>(_alias, _args_quantity, _function));
  289.         }
  290.         else {
  291.                 root = new Node_function<T>(_alias, _args_quantity, *_function);
  292.         }
  293.  
  294.         _return.set_return_code(no_error);
  295.         _return.set_value(true);
  296.         return _return;
  297. }
  298.  
  299.  
  300. /**
  301. Add new node containing variable in first empty place found by preorder algorithm.
  302.  
  303. @_alias Name of variable
  304. */
  305. template <class T> RETURN<bool> Tree<T>::add_variable(std::string _alias) {
  306.         RETURN<bool> _return;
  307.         if (_alias == "") {
  308.                 _return.set_return_code(error);
  309.                 _return.set_value(false);
  310.                 _return.set_message("Variable must have a name");
  311.                 return _return;
  312.         }
  313.  
  314.         if (root != nullptr) {
  315.                 if (root->is_completed()) {
  316.                         _return.set_return_code(warning);
  317.                         _return.set_value(false);
  318.                         _return.set_message("Tree is already complete");
  319.                         return _return;
  320.                 }
  321.  
  322.                 set_new(root, new Node_variable<T>(_alias));
  323.         }
  324.         else {
  325.                 root = new Node_variable<T>(_alias);
  326.         }
  327.  
  328.         _return.set_return_code(no_error);
  329.         _return.set_value(true);
  330.         return _return;
  331. }
  332.  
  333. /**
  334. Add new node containg constant in first empty place found by preorder algorithm
  335.  
  336. @_value Value of constant
  337. */
  338. template <class T> RETURN<bool> Tree<T>::add_constant(T _value) {
  339.         RETURN<bool> _return;
  340.  
  341.         if (root != nullptr) {
  342.                 if (root->is_completed()) {
  343.                         _return.set_return_code(warning);
  344.                         _return.set_value(false);
  345.                         _return.set_message("Tree is already complete");
  346.                         return _return;
  347.                 }
  348.  
  349.                 set_new(root, new Node_constant<T>(std::to_string(_value), _value));
  350.         }
  351.         else {
  352.                 root = new Node_constant<T>(std::to_string(_value), _value);
  353.         }
  354.  
  355.         _return.set_return_code(no_error);
  356.         _return.set_value(true);
  357.         return _return;
  358. }
  359.  
  360. template <class T> RETURN<bool> Tree<T>::is_completed() const {
  361.         RETURN<bool> _return;
  362.  
  363.         if (root == nullptr) {
  364.                 _return.set_value(false);
  365.         }
  366.         else {
  367.                 _return.set_value(root->is_completed());
  368.         }
  369.  
  370.         _return.set_return_code(no_error);
  371.         return _return;
  372. }
  373.  
  374. /**
  375. Calculate value of whole tree
  376.  
  377. @_args Array of values to be put in variables nodes
  378. */
  379. template <class T> RETURN<T> Tree<T>::calculate(int _args_quantity, T *_args) {
  380.         RETURN<T> _result;
  381.  
  382.         if (_args_quantity < get_variables().size()) {
  383.                 _result.set_return_code(error);
  384.                 _result.set_message("Not enough arguments");
  385.                 return _result;
  386.         }
  387.         if (root == nullptr) {
  388.                 _result.set_return_code(warning);
  389.                 _result.set_message("The tree is empty");
  390.                 return _result;
  391.         }
  392.         else if (!root->is_completed()) {
  393.                 _result.set_return_code(error);
  394.                 _result.set_message("The tree is uncompleted");
  395.                 return _result;
  396.         }
  397.  
  398.         /* Move through tree and assign all values to nodes containg variables */
  399.         int i = 0;
  400.         std::stack<Node<T>*> stack;
  401.         stack.push(root);
  402.         while (!stack.empty()) {
  403.                 Node<T> *current = stack.top();
  404.  
  405.                 if (Node_variable<T> *var = dynamic_cast<Node_variable<T>*>(current)) {
  406.                         var->set_args(&_args[i]);
  407.                         i++;
  408.                 }
  409.  
  410.                 stack.pop();
  411.                 for (int i = current->childrens.size() - 1; i >= 0; i--) {
  412.                         stack.push(current->childrens.at(i));
  413.                 }
  414.         }
  415.  
  416.         /* Return value */
  417.         _result.set_return_code(no_error);
  418.         _result.set_value(root->get_value());
  419.         return _result;
  420. }
  421.  
  422. /**
  423. Prints names of all variables in tree without repetitions
  424. */
  425. template <class T> RETURN<std::string> Tree<T>::vars() const {
  426.         RETURN<std::string> _result;
  427.         std::string result = "";
  428.         std::vector<std::string> variables;
  429.  
  430.         for (int i = 0; i < get_variables().size(); i++) {
  431.                 if (std::find(variables.begin(), variables.end(), get_variables().at(i)->get_alias()) == variables.end()) {
  432.                         variables.push_back(get_variables().at(i)->get_alias());
  433.                         result += variables.at(i) + ' ';
  434.                 }
  435.         }
  436.        
  437.         _result.set_return_code(no_error);
  438.         _result.set_value(result);
  439.         return _result;
  440. }
  441.  
  442. template <class T> RETURN<std::string> Tree<T>::print() const {
  443.         RETURN<std::string> _return;
  444.         std::string result = "";
  445.  
  446.         std::stack<Node<T>*> stack;
  447.         stack.push(root);
  448.         while (!stack.empty()) {
  449.                 Node<T> *current = stack.top();
  450.  
  451.  
  452.                 result += current->alias + ' ';
  453.  
  454.                 stack.pop();
  455.                 for (int i = current->childrens.size() - 1; i >= 0; i--) {
  456.                         stack.push(current->childrens.at(i));
  457.                 }
  458.         }
  459.  
  460.         _return.set_return_code(no_error);
  461.         _return.set_value(result);
  462.         return _return;
  463. }
  464.  
  465. /**
  466. Assignment operator overload
  467. */
  468. template <class T> Tree<T>& Tree<T>::operator=(const Tree<T> &_other) {
  469.         if (this == &_other) return *this;
  470.  
  471.         /* Dealocate memoey */
  472.         delete root;
  473.         root = nullptr;
  474.  
  475.         /* Move through _other tree and copy all nodes */
  476.         std::stack<Node<T>*> stack;
  477.         stack.push(_other.root);
  478.         while (!stack.empty()) {
  479.                 Node<T>* current = stack.top();
  480.  
  481.                 if (Node_function<T> *fun = dynamic_cast<Node_function<T>*>(current)) {
  482.                         add_function(fun->get_alias(), fun->get_childrens_quantity(), fun->function);
  483.  
  484.                 }
  485.                 else if (Node_variable<T> *var = dynamic_cast<Node_variable<T>*>(current)) {
  486.                         add_variable(var->get_alias());
  487.  
  488.                 }
  489.                 else if (Node_constant<T> *con = dynamic_cast<Node_constant<T>*>(current)) {
  490.                         add_constant(con->get_value());
  491.                 }
  492.  
  493.                 stack.pop();
  494.                 for (int i = current->childrens.size() - 1; i >= 0; i--) {
  495.                         stack.push(current->childrens.at(i));
  496.                 }
  497.         }
  498.  
  499.         return *this;
  500. }
  501.  
  502. /**
  503.  
  504. */
  505. template <class T> Tree<T>& Tree<T>::operator+(const Tree<T> &_other) const {
  506.         Tree<T> result;
  507.         result = *this;
  508.         Node<T>* current = result.root;
  509.  
  510.         if (current->childrens.size() > 0) {
  511.                 std::srand (time(NULL));
  512.        
  513.                 int i = rand() % current->childrens.size();
  514.                 Node_function<T> *fun = dynamic_cast<Node_function<T>*>(current->childrens.at(i));
  515.                 Node_variable<T> *var = dynamic_cast<Node_variable<T>*>(current->childrens.at(i));
  516.                 Node_constant<T> *con = dynamic_cast<Node_constant<T>*>(current->childrens.at(i));
  517.                 while (!fun || !var || !con){
  518.                         current = current->childrens.at(i);
  519.  
  520.                         fun = dynamic_cast<Node_function<T>*>(current->childrens.at(i));
  521.                         var = dynamic_cast<Node_variable<T>*>(current->childrens.at(i));
  522.                         con = dynamic_cast<Node_constant<T>*>(current->childrens.at(i));
  523.                 }
  524.  
  525.                 delete current->childrens.at(i);
  526.                 fun = dynamic_cast<Node_function<T>*>(_other.root);
  527.                 var = dynamic_cast<Node_variable<T>*>(_other.root);
  528.                 con = dynamic_cast<Node_constant<T>*>(_other.root);
  529.                 if (fun) {
  530.                         current->childrens.at(i) = new Node_function<T>(fun->alias, fun->childrens_quantity, fun->function);
  531.                 } else if (var) {
  532.                         current->childrens.at(i) = new Node_variable<T>(var->alias);
  533.                 } else {
  534.                         current->childrens.at(i) = new Node_constant<T>(std::to_string(con->get_value()), con->get_value());
  535.                 }
  536.         }
  537.  
  538.         return result;
  539. }
  540.  
  541. /**
  542. Adds given node in first empty place found by preorder algorithm which starts searching from pointed node
  543.  
  544. @_begin Node from which searching starts
  545. @_new_node New node to be added
  546. */
  547. template <class T> void Tree<T>::set_new(Node<T> *_begin, Node<T> *_new_node) {
  548.         bool added = false;                             //Condition of while loop
  549.         Node<T> *current = _begin;              //Currently used node
  550.  
  551.                                                                         /* Searching loop */
  552.         while (!added) {
  553.                 /* Iterate throught all already completed childes of current node, that is having all childrens */
  554.                 int i = 0;
  555.                 while (i < current->childrens.size() && current->childrens.at(i)->is_completed()) {
  556.                         i++;
  557.                 }
  558.  
  559.                 /* Decide if move to next child or add new node */
  560.                 if (i < current->childrens.size() && !current->childrens.at(i)->is_completed()) {
  561.                         /* Found uncompleted child */
  562.                         current = current->childrens.at(i);
  563.                 }
  564.                 else {
  565.                         /* All previous childs are complete, thus add new node as child */
  566.                         current->childrens.push_back(_new_node);
  567.                         added = true;
  568.                 }
  569.         }
  570. }
  571.  
  572. /**
  573. Print tree in preorder
  574. */
  575. template <class T> void Tree<T>::preorder(Node<T> *_current) const {
  576.         std::cout << _current->get_alias() << ' ';
  577.  
  578.         for (int i = 0; i < _current->childrens.size(); i++) {
  579.                 if (_current->childrens[i] != nullptr) {
  580.                         preorder(_current->childrens[i]);
  581.                 }
  582.         }
  583. }
  584.  
  585. /**
  586.  
  587. */
  588. template <class T> std::vector<Node<T>*> Tree<T>::get_variables() const {
  589.         std::vector<Node<T>*> variables;
  590.         std::stack<Node<T>*> stack;
  591.         stack.push(root);
  592.         while (!stack.empty()) {
  593.                 Node<T> *current = stack.top();
  594.  
  595.                 if (Node_variable<T> *var = dynamic_cast<Node_variable<T>*>(current)) {
  596.                         variables.push_back(var);
  597.                 }
  598.  
  599.                 stack.pop();
  600.                 for (int i = current->childrens.size() - 1; i >= 0; i--) {
  601.                         stack.push(current->childrens.at(i)); ///
  602.                 }
  603.         }
  604.  
  605.         return variables;
  606. }
  607.  
  608. #pragma once
  609. #include <iostream>
  610. #include <string>
  611. enum return_code { no_error, warning, error };
  612.  
  613. template <class T> class RETURN {
  614. public:
  615.         RETURN();
  616.         RETURN(return_code _rc);
  617.         RETURN(const T& _value);
  618.  
  619.         void set_return_code(return_code _rc);
  620.         void set_message(std::string _message);
  621.         void add_message(std::string _message);
  622.         void set_value(T _value);
  623.         bool is_error() const;
  624.         T get_value() const;
  625.  
  626.         std::string get_message() const;
  627.  
  628.         RETURN<T>& operator=(const RETURN<T> &_other);
  629.  
  630. private:
  631.         T value;
  632.         return_code rc;
  633.         std::string message;
  634. };
  635.  
  636. template <class T> RETURN<T>::RETURN() :
  637.         message(""){
  638. }
  639.  
  640. template <class T> RETURN<T>::RETURN(return_code _rc) :
  641.         rc(_rc),
  642.         message("") {
  643.         }
  644.  
  645. template <class T> RETURN<T>::RETURN(const T& _value) :
  646.         rc(no_error),
  647.         message(""),
  648.         value(_value) {
  649.  
  650. }
  651.  
  652. template <class T> void RETURN<T>::set_return_code(return_code _rc) {
  653.         rc = _rc;
  654. }
  655.  
  656. template <class T> void RETURN<T>::set_message(std::string _message) {
  657.         message = _message;
  658. }
  659.  
  660. template <class T> void RETURN<T>::add_message(std::string _message) {
  661.         message += _message;
  662. }
  663.  
  664. template <class T> void RETURN<T>::set_value(T _value) {
  665.         value = _value;
  666. }
  667.  
  668. template <class T> T RETURN<T>::get_value() const {
  669.         return value;
  670. }
  671.  
  672. template <class T> bool RETURN<T>::is_error() const {
  673.         return rc == error;
  674. }
  675.  
  676. template <class T> std::string RETURN<T>::get_message() const {
  677.         return message;
  678. }
  679.  
  680. template<class T> RETURN<T>& RETURN<T>::operator=(const RETURN<T> &_other){
  681.         if (this == &_other) return *this;
  682.  
  683.         value = _other.value;
  684.         rc = _other.rc;
  685.         message = _other.message;
  686.         return *this;
  687. }
  688.  
  689. #include "stdafx.h"
  690. #include "header.h"
  691. #include "Function.h"
  692.  
  693. double add(double *args) {
  694.         return args[0] + args[1];
  695. }
  696.  
  697. double sin(double *args) {
  698.         return std::sin(*args);
  699. }
  700.  
  701. double subtract(double *args) {
  702.         return args[0] - args[1];
  703. }
  704.  
  705. int main() {
  706. {
  707.         Tree<double> t;
  708.         t.add_function("+", 2, &add);
  709.         t.add_function("-", 2, &subtract);
  710.         t.add_constant(1);
  711.         t.add_constant(2);
  712.         t.add_constant(3);
  713.  
  714.         Tree<double> t2;
  715.         t2.add_function("sin", 1, &sin);
  716.         t2.add_constant(4);
  717.  
  718.         Tree<double> res;
  719.         res = t + t2;
  720. }
  721.         std::cin.get();
  722.     return 0;
  723. }