- #pragma once
- #include <iostream>
- #include <cmath>
- #include "Tree.h"
- #include "Node_function.h"
- #include "Node_variable.h"
- #include "Node_constant.h"
- #include "RETURN.h"
- #include "User.h"
- #pragma once
- #include <iostream>
- #include <vector>
- template <class T> class Node {
- template <class T> friend class Tree;
- public:
- Node(int _children_quantity, std::string _alias);
- virtual ~Node();
- virtual void set_args(T *_args) = 0;
- virtual bool is_completed() const = 0;
- virtual T get_value() const = 0;
- int get_childrens_quantity() const;
- std::string get_alias() const;
- //protected:
- int childrens_quantity;
- std::string alias;
- std::vector<Node<T>*> childrens;
- };
- //--------------------------------------------------------
- template <class T> Node<T>::Node(int _children_quantity, std::string _alias) :
- childrens_quantity(_children_quantity),
- alias(_alias) {
- }
- template <class T> Node<T>::~Node() {
- std::cout << "Destroy: " + alias << '\n';
- for (int i = 0; i < childrens.size(); i++) {
- delete childrens.at(i);
- }
- }
- template <class T> std::string Node<T>::get_alias() const {
- return alias;
- }
- template <class T> int Node<T>::get_childrens_quantity () const {
- return childrens_quantity;
- }
- #pragma once
- #include "Node.h"
- template <class T> class Node_constant : public Node<T> {
- template <class T> friend class Tree;
- public:
- Node_constant(std::string _alias, T _value);
- ~Node_constant();
- void set_args(T *_args);
- bool is_completed() const;
- T get_value() const;
- //private:
- T value;
- };
- //--------------------------------------------------------
- template <class T> Node_constant<T>::Node_constant(std::string _alias, T _value) :
- Node(0, _alias),
- value(_value){
- }
- template <class T> Node_constant<T>::~Node_constant() {
- }
- template <class T> void Node_constant<T>::set_args(T *_args) {
- value = *_args;
- }
- template <class T> bool Node_constant<T>::is_completed() const {
- return true;
- }
- template <class T> T Node_constant<T>::get_value() const {
- return value;
- }
- #pragma once
- #include "Node.h"
- template <class T> class Node_variable : public Node<T> {
- template <class T> friend class Tree;
- public:
- Node_variable(std::string _alias);
- ~Node_variable();
- void set_args(T *_args);
- bool is_completed() const;
- T get_value() const;
- //private:
- T value;
- };
- //--------------------------------------------------------
- template <class T> Node_variable<T>::Node_variable(std::string _alias) :
- Node(0, _alias),
- value(NULL) {
- }
- template <class T> Node_variable<T>::~Node_variable() {
- }
- template <class T> void Node_variable<T>::set_args(T *_args) {
- value = *_args;
- }
- template <class T> bool Node_variable<T>::is_completed() const {
- return true;
- }
- template <class T> T Node_variable<T>::get_value() const {
- return value;
- }
- #pragma once
- #include "Node.h"
- template <class T> class Node_function : public Node<T> {
- template <class T> friend class Tree;
- public:
- Node_function(std::string _alias, int _args_quantity, T (*_function)(T *_args));
- ~Node_function();
- void set_args(T *_args);
- bool is_completed() const;
- T get_value() const;
- //private:
- T *args;
- T (*function)(T *args);
- };
- //--------------------------------------------------------
- template <class T> Node_function<T>::Node_function(std::string _alias, int _args_quantity, T(*_function)(T *_args)) :
- Node(_args_quantity, _alias),
- args(new T[_args_quantity]),
- function(_function){
- }
- template <class T> Node_function<T>::~Node_function() {
- delete args;
- }
- template <class T> void Node_function<T>::set_args(T *_args) {
- args = _args;
- }
- template <class T> bool Node_function<T>::is_completed() const {
- bool result = childrens_quantity == childrens.size();
- int i = 0;
- while (i < childrens_quantity && result) {
- if (childrens.at(i) == nullptr) {
- result = false;
- } else {
- result = childrens.at(i)->is_completed();
- }
- i++;
- }
- return result;
- }
- template <class T> T Node_function<T>::get_value() const {
- for (int i = 0; i < childrens.size(); i++) {
- args[i] = childrens.at(i)->get_value();
- }
- return function(args);
- }
- #pragma once
- #include <iostream>
- #include <string>
- #include <stack>
- #include <vector>
- #include <algorithm>
- #include <stdlib.h>
- #include <time.h>
- #include "Node_function.h"
- #include "Node_variable.h"
- #include "Node_constant.h"
- #include "RETURN.h"
- template <class T> class Tree {
- public:
- Tree();
- ~Tree();
- RETURN<bool> add_function(std::string _alias, int _args_quantity, T (*_function)(T *_args));
- RETURN<bool> add_variable(std::string _alias);
- RETURN<bool> add_constant(T _value);
- RETURN<bool> is_completed() const;
- RETURN<T> calculate(int _args_quantity, T *_args);
- RETURN<std::string> vars() const;
- RETURN<std::string> print() const;
- Tree<T>& operator=(const Tree<T> &_other);
- Tree<T>& operator+(const Tree<T> &_other) const;
- //private:
- void set_new(Node<T> *_begin, Node<T> *_new_node);
- void preorder(Node<T> *_current) const;
- std::vector<Node<T>*> get_variables() const;
- Node<T> *root;
- };
- /**
- Create new Tree and set root as NULL
- */
- template <class T> Tree<T>::Tree() :
- root(nullptr) {
- }
- /**
- Delete Tree, nodes are being deleted in preorder
- */
- template <class T> Tree<T>::~Tree() {
- std::cout << "delete: " << '\n';
- delete root;
- }
- /**
- Add new node containing function in first empty place found by preorder algorithm
- @_alias Name of function
- @_args_quantity How many arguments function takes
- @_function Pointer to function to storage in node
- */
- template <class T> RETURN<bool> Tree<T>::add_function(std::string _alias, int _args_quantity, T(*_function)(T *_args)) {
- RETURN<bool> _return;
- if (_args_quantity < 0) {
- _return.set_return_code(error);
- _return.set_value(false);
- _return.set_message("Function cannot take negative amount of arguments");
- return _return;
- }
- if (_function == nullptr) {
- _return.set_return_code(error);
- _return.set_value(false);
- _return.set_message("Pointer to function cannto be null");
- return _return;
- }
- if (root != nullptr) {
- if (root->is_completed()) {
- _return.set_return_code(warning);
- _return.set_message("Tree is already complete");
- return _return;
- }
- set_new(root, new Node_function<T>(_alias, _args_quantity, _function));
- }
- else {
- root = new Node_function<T>(_alias, _args_quantity, *_function);
- }
- _return.set_return_code(no_error);
- _return.set_value(true);
- return _return;
- }
- /**
- Add new node containing variable in first empty place found by preorder algorithm.
- @_alias Name of variable
- */
- template <class T> RETURN<bool> Tree<T>::add_variable(std::string _alias) {
- RETURN<bool> _return;
- if (_alias == "") {
- _return.set_return_code(error);
- _return.set_value(false);
- _return.set_message("Variable must have a name");
- return _return;
- }
- if (root != nullptr) {
- if (root->is_completed()) {
- _return.set_return_code(warning);
- _return.set_value(false);
- _return.set_message("Tree is already complete");
- return _return;
- }
- set_new(root, new Node_variable<T>(_alias));
- }
- else {
- root = new Node_variable<T>(_alias);
- }
- _return.set_return_code(no_error);
- _return.set_value(true);
- return _return;
- }
- /**
- Add new node containg constant in first empty place found by preorder algorithm
- @_value Value of constant
- */
- template <class T> RETURN<bool> Tree<T>::add_constant(T _value) {
- RETURN<bool> _return;
- if (root != nullptr) {
- if (root->is_completed()) {
- _return.set_return_code(warning);
- _return.set_value(false);
- _return.set_message("Tree is already complete");
- return _return;
- }
- set_new(root, new Node_constant<T>(std::to_string(_value), _value));
- }
- else {
- root = new Node_constant<T>(std::to_string(_value), _value);
- }
- _return.set_return_code(no_error);
- _return.set_value(true);
- return _return;
- }
- template <class T> RETURN<bool> Tree<T>::is_completed() const {
- RETURN<bool> _return;
- if (root == nullptr) {
- _return.set_value(false);
- }
- else {
- _return.set_value(root->is_completed());
- }
- _return.set_return_code(no_error);
- return _return;
- }
- /**
- Calculate value of whole tree
- @_args Array of values to be put in variables nodes
- */
- template <class T> RETURN<T> Tree<T>::calculate(int _args_quantity, T *_args) {
- RETURN<T> _result;
- if (_args_quantity < get_variables().size()) {
- _result.set_return_code(error);
- _result.set_message("Not enough arguments");
- return _result;
- }
- if (root == nullptr) {
- _result.set_return_code(warning);
- _result.set_message("The tree is empty");
- return _result;
- }
- else if (!root->is_completed()) {
- _result.set_return_code(error);
- _result.set_message("The tree is uncompleted");
- return _result;
- }
- /* Move through tree and assign all values to nodes containg variables */
- int i = 0;
- std::stack<Node<T>*> stack;
- stack.push(root);
- while (!stack.empty()) {
- Node<T> *current = stack.top();
- if (Node_variable<T> *var = dynamic_cast<Node_variable<T>*>(current)) {
- var->set_args(&_args[i]);
- i++;
- }
- stack.pop();
- for (int i = current->childrens.size() - 1; i >= 0; i--) {
- stack.push(current->childrens.at(i));
- }
- }
- /* Return value */
- _result.set_return_code(no_error);
- _result.set_value(root->get_value());
- return _result;
- }
- /**
- Prints names of all variables in tree without repetitions
- */
- template <class T> RETURN<std::string> Tree<T>::vars() const {
- RETURN<std::string> _result;
- std::string result = "";
- std::vector<std::string> variables;
- for (int i = 0; i < get_variables().size(); i++) {
- if (std::find(variables.begin(), variables.end(), get_variables().at(i)->get_alias()) == variables.end()) {
- variables.push_back(get_variables().at(i)->get_alias());
- result += variables.at(i) + ' ';
- }
- }
- _result.set_return_code(no_error);
- _result.set_value(result);
- return _result;
- }
- template <class T> RETURN<std::string> Tree<T>::print() const {
- RETURN<std::string> _return;
- std::string result = "";
- std::stack<Node<T>*> stack;
- stack.push(root);
- while (!stack.empty()) {
- Node<T> *current = stack.top();
- result += current->alias + ' ';
- stack.pop();
- for (int i = current->childrens.size() - 1; i >= 0; i--) {
- stack.push(current->childrens.at(i));
- }
- }
- _return.set_return_code(no_error);
- _return.set_value(result);
- return _return;
- }
- /**
- Assignment operator overload
- */
- template <class T> Tree<T>& Tree<T>::operator=(const Tree<T> &_other) {
- if (this == &_other) return *this;
- /* Dealocate memoey */
- delete root;
- root = nullptr;
- /* Move through _other tree and copy all nodes */
- std::stack<Node<T>*> stack;
- stack.push(_other.root);
- while (!stack.empty()) {
- Node<T>* current = stack.top();
- if (Node_function<T> *fun = dynamic_cast<Node_function<T>*>(current)) {
- add_function(fun->get_alias(), fun->get_childrens_quantity(), fun->function);
- }
- else if (Node_variable<T> *var = dynamic_cast<Node_variable<T>*>(current)) {
- add_variable(var->get_alias());
- }
- else if (Node_constant<T> *con = dynamic_cast<Node_constant<T>*>(current)) {
- add_constant(con->get_value());
- }
- stack.pop();
- for (int i = current->childrens.size() - 1; i >= 0; i--) {
- stack.push(current->childrens.at(i));
- }
- }
- return *this;
- }
- /**
- */
- template <class T> Tree<T>& Tree<T>::operator+(const Tree<T> &_other) const {
- Tree<T> result;
- result = *this;
- Node<T>* current = result.root;
- if (current->childrens.size() > 0) {
- std::srand (time(NULL));
- int i = rand() % current->childrens.size();
- Node_function<T> *fun = dynamic_cast<Node_function<T>*>(current->childrens.at(i));
- Node_variable<T> *var = dynamic_cast<Node_variable<T>*>(current->childrens.at(i));
- Node_constant<T> *con = dynamic_cast<Node_constant<T>*>(current->childrens.at(i));
- while (!fun || !var || !con){
- current = current->childrens.at(i);
- fun = dynamic_cast<Node_function<T>*>(current->childrens.at(i));
- var = dynamic_cast<Node_variable<T>*>(current->childrens.at(i));
- con = dynamic_cast<Node_constant<T>*>(current->childrens.at(i));
- }
- delete current->childrens.at(i);
- fun = dynamic_cast<Node_function<T>*>(_other.root);
- var = dynamic_cast<Node_variable<T>*>(_other.root);
- con = dynamic_cast<Node_constant<T>*>(_other.root);
- if (fun) {
- current->childrens.at(i) = new Node_function<T>(fun->alias, fun->childrens_quantity, fun->function);
- } else if (var) {
- current->childrens.at(i) = new Node_variable<T>(var->alias);
- } else {
- current->childrens.at(i) = new Node_constant<T>(std::to_string(con->get_value()), con->get_value());
- }
- }
- return result;
- }
- /**
- Adds given node in first empty place found by preorder algorithm which starts searching from pointed node
- @_begin Node from which searching starts
- @_new_node New node to be added
- */
- template <class T> void Tree<T>::set_new(Node<T> *_begin, Node<T> *_new_node) {
- bool added = false; //Condition of while loop
- Node<T> *current = _begin; //Currently used node
- /* Searching loop */
- while (!added) {
- /* Iterate throught all already completed childes of current node, that is having all childrens */
- int i = 0;
- while (i < current->childrens.size() && current->childrens.at(i)->is_completed()) {
- i++;
- }
- /* Decide if move to next child or add new node */
- if (i < current->childrens.size() && !current->childrens.at(i)->is_completed()) {
- /* Found uncompleted child */
- current = current->childrens.at(i);
- }
- else {
- /* All previous childs are complete, thus add new node as child */
- current->childrens.push_back(_new_node);
- added = true;
- }
- }
- }
- /**
- Print tree in preorder
- */
- template <class T> void Tree<T>::preorder(Node<T> *_current) const {
- std::cout << _current->get_alias() << ' ';
- for (int i = 0; i < _current->childrens.size(); i++) {
- if (_current->childrens[i] != nullptr) {
- preorder(_current->childrens[i]);
- }
- }
- }
- /**
- */
- template <class T> std::vector<Node<T>*> Tree<T>::get_variables() const {
- std::vector<Node<T>*> variables;
- std::stack<Node<T>*> stack;
- stack.push(root);
- while (!stack.empty()) {
- Node<T> *current = stack.top();
- if (Node_variable<T> *var = dynamic_cast<Node_variable<T>*>(current)) {
- variables.push_back(var);
- }
- stack.pop();
- for (int i = current->childrens.size() - 1; i >= 0; i--) {
- stack.push(current->childrens.at(i)); ///
- }
- }
- return variables;
- }
- #pragma once
- #include <iostream>
- #include <string>
- enum return_code { no_error, warning, error };
- template <class T> class RETURN {
- public:
- RETURN();
- RETURN(return_code _rc);
- RETURN(const T& _value);
- void set_return_code(return_code _rc);
- void set_message(std::string _message);
- void add_message(std::string _message);
- void set_value(T _value);
- bool is_error() const;
- T get_value() const;
- std::string get_message() const;
- RETURN<T>& operator=(const RETURN<T> &_other);
- private:
- T value;
- return_code rc;
- std::string message;
- };
- template <class T> RETURN<T>::RETURN() :
- message(""){
- }
- template <class T> RETURN<T>::RETURN(return_code _rc) :
- rc(_rc),
- message("") {
- }
- template <class T> RETURN<T>::RETURN(const T& _value) :
- rc(no_error),
- message(""),
- value(_value) {
- }
- template <class T> void RETURN<T>::set_return_code(return_code _rc) {
- rc = _rc;
- }
- template <class T> void RETURN<T>::set_message(std::string _message) {
- message = _message;
- }
- template <class T> void RETURN<T>::add_message(std::string _message) {
- message += _message;
- }
- template <class T> void RETURN<T>::set_value(T _value) {
- value = _value;
- }
- template <class T> T RETURN<T>::get_value() const {
- return value;
- }
- template <class T> bool RETURN<T>::is_error() const {
- return rc == error;
- }
- template <class T> std::string RETURN<T>::get_message() const {
- return message;
- }
- template<class T> RETURN<T>& RETURN<T>::operator=(const RETURN<T> &_other){
- if (this == &_other) return *this;
- value = _other.value;
- rc = _other.rc;
- message = _other.message;
- return *this;
- }
- #include "stdafx.h"
- #include "header.h"
- #include "Function.h"
- double add(double *args) {
- return args[0] + args[1];
- }
- double sin(double *args) {
- return std::sin(*args);
- }
- double subtract(double *args) {
- return args[0] - args[1];
- }
- int main() {
- {
- Tree<double> t;
- t.add_function("+", 2, &add);
- t.add_function("-", 2, &subtract);
- t.add_constant(1);
- t.add_constant(2);
- t.add_constant(3);
- Tree<double> t2;
- t2.add_function("sin", 1, &sin);
- t2.add_constant(4);
- Tree<double> res;
- res = t + t2;
- }
- std::cin.get();
- return 0;
- }