Facebook
From Cobalt Partdridge, 6 Years ago, written in C++.
Embed
Download Paste or View Raw
Hits: 271
  1. #include "stdafx.h"
  2. #include "CInterFace.h"
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7. int main()
  8. {
  9.         {
  10.                 CInterFace c_interFace;
  11.                 while (c_interFace.iGetAndExecuteCommand() != -1)
  12.                 {
  13.                         cout << "_______________________" << endl;
  14.                 }
  15.         }
  16.  
  17.         return 0;
  18. }
  19.  
  20.  
  21. #pragma once
  22. #include <string>
  23. using namespace std;
  24.  
  25. #define S_UNDEFINED "undef"
  26. #define I_ERR_OK 0
  27. #define I_ERR_VAR_WITH_INVALID_CHAR 1
  28. #define S_ERR_VAR_WITH_INVALID_CHAR "Variable(s) with invalid char, loaded as: "
  29.  
  30. class CNode
  31. {
  32.  
  33.         enum e_nodeType
  34.         {
  35.                 op1arg, op2arg, value, variable
  36.         };
  37.         friend class CTree;
  38. public:
  39.         CNode(string sValue);
  40.         CNode(CNode &cOther);
  41.         ~CNode();
  42.  
  43. private:
  44.         bool IsAnInteger();
  45.         bool IsOneArgOperator();
  46.         bool IsTwoArgsOperator();
  47.         bool IsVariable();
  48.         int SetTypeAndMaxChildren();
  49.         string toString();
  50.  
  51.         string _value;
  52.         CNode **_children;
  53.         int _maxChildren;
  54.         int _definedChildren;
  55.  
  56.         e_nodeType e_type;
  57. };
  58.  
  59.  
  60. #include "stdafx.h"
  61. #include "CNode.h"
  62.  
  63. CNode::CNode(string sValue)
  64. {
  65.         _value = sValue;
  66.         _definedChildren = 0;
  67.         SetTypeAndMaxChildren();
  68.         if (_maxChildren > 0)
  69.         {
  70.                 _children = new CNode*[_maxChildren];
  71.         }
  72.         else
  73.         {
  74.                 _children = nullptr;
  75.         }
  76. }
  77.  
  78. CNode::CNode(CNode &cOther)
  79. {
  80.         _value = cOther._value;
  81.         _maxChildren = cOther._maxChildren;
  82.         e_type = cOther.e_type;
  83.  
  84.         if (_maxChildren > 0)
  85.         {
  86.                 _children = new CNode*[_maxChildren];
  87.                 for (_definedChildren = 0; _definedChildren < _maxChildren; _definedChildren++)
  88.                 {
  89.                         *(_children + _definedChildren) = new CNode(**(cOther._children + _definedChildren));
  90.                 }
  91.         }
  92.         else
  93.         {
  94.                 _children = nullptr;
  95.         }
  96. }
  97.  
  98. CNode::~CNode()
  99. {
  100.         if (_children != nullptr)
  101.         {
  102.                 for (int i = 0; i < _maxChildren; i++)
  103.                 {
  104.                         delete *(_children + i);
  105.                 }
  106.                 delete _children;
  107.                 _children = nullptr;
  108.         }
  109. }
  110.  
  111. bool CNode::IsAnInteger()
  112. {
  113.         return (_value.find_first_not_of("0123456789") == string::npos);
  114. }
  115.  
  116. bool CNode::IsOneArgOperator()
  117. {
  118.         return (_value == "sin" || _value == "cos");
  119. }
  120.  
  121. bool CNode::IsTwoArgsOperator()
  122. {
  123.         return (_value == "+" || _value == "-" || _value == "*" || _value == "/");
  124. }
  125.  
  126. bool CNode::IsVariable()
  127. {
  128.         bool bIsVar = true;
  129.         int i_size = _value.size();
  130.         for (int i = 0; i < i_size && bIsVar; i++)
  131.         {
  132.                 char c_char = _value.at(i);
  133.                 if (c_char < 48 || c_char > 122 || (c_char > 57 && c_char < 65) || (c_char > 90 && c_char < 97))
  134.                 {
  135.                         bIsVar = false;
  136.                 }
  137.         }
  138.         return bIsVar;
  139. }
  140.  
  141. int CNode::SetTypeAndMaxChildren()
  142. {
  143.         if (IsAnInteger())
  144.         {
  145.                 e_type = value;
  146.                 _maxChildren = 0;
  147.         }
  148.         else if (IsTwoArgsOperator())
  149.         {
  150.                 e_type = op2arg;
  151.                 _maxChildren = 2;
  152.         }
  153.         else if (IsOneArgOperator())
  154.         {
  155.                 e_type = op1arg;
  156.                 _maxChildren = 1;
  157.         }
  158.         else
  159.         {
  160.                 e_type = variable;
  161.                 _maxChildren = 0;
  162.                 if (!IsVariable())
  163.                 {
  164.                         _value = S_UNDEFINED;
  165.                         return I_ERR_VAR_WITH_INVALID_CHAR;
  166.                 }
  167.         }
  168.         return I_ERR_OK;
  169. }
  170.  
  171.  
  172. string CNode::toString()
  173. {
  174.         string s_retString = _value;
  175.         for (int i = 0; i < _maxChildren; i++)
  176.         {
  177.                 s_retString += (" " + (*(_children + i))->toString());
  178.         }
  179.         return s_retString;
  180. }
  181.  
  182.  
  183. #pragma once
  184. #include "CNode.h"
  185. #include <iostream>
  186. #include <vector>
  187.  
  188. #define S_DEF_VAL "1"
  189. #define S_OP_SIN "sin"
  190. #define S_OP_COS "cos"
  191. #define S_OP_ADD "+"
  192. #define S_OP_SUB "-"
  193. #define S_OP_MUL "*"
  194. #define S_OP_DIV "/"
  195. #define S_NOT_DEFINED_DEBUG_LOG "Not defined operation!"
  196.  
  197. #define I_ERR_EMPTY_TREE 2
  198. #define S_ERR_EMPTY_TREE "Tree is empty!"
  199. #define I_ERR_DIV_BY_ZERO 3
  200. #define S_ERR_DIV_BY_ZERO "Dividing by zero!"
  201. #define I_ERR_INVALID_EXPRESSION 4
  202. #define S_ERR_IVALID_EXPRESSION "Invalid expresion! Loaded:\n"
  203.  
  204.  
  205. class CTree
  206. {
  207. public:
  208.         CTree();
  209.         CTree(CTree &cOther);
  210.         ~CTree();
  211.         CTree operator +(CTree &other);
  212.         void operator =(CTree &other);
  213.         vector<string>& vctrGetVariableVector();
  214.         int BuildTree(vector<string> &vctrLoadedTokens);
  215.         string toString();
  216.         double Evaluate(vector<int> &vctrLoadedVariables, int &iErrorCode);
  217.  
  218. private:
  219.         void AddIfNewVariable(string &sVariableName);
  220.         void DeleteIfWasVariable(string &sVariableName);
  221.         int BuildSubTree(CNode*& pcRootNode, vector<string> &vctrLoadedTokens);
  222.         int ValueForVariable(string sVarName, vector<int> &vctrLoadedVariables);
  223.         double CalculateSubtree(CNode *pcRootNode, vector<int> &vctrLoadedVariables, int &iErrorCode);
  224.  
  225.         CNode *_root;
  226.         vector<string> _variables;
  227. };
  228.  
  229.  
  230. #include "stdafx.h"
  231. #include "CTree.h"
  232.  
  233.  
  234. CTree::CTree()
  235. {
  236.         _root = nullptr;
  237. }
  238.  
  239. CTree::CTree(CTree &cOther)
  240. {
  241.         _variables = cOther._variables;
  242.         _root = new CNode(*cOther._root);
  243. }
  244.  
  245.  
  246. CTree::~CTree()
  247. {
  248.         if (_root != nullptr)
  249.         {
  250.                 delete _root;
  251.                 _root = nullptr;
  252.         }
  253. }
  254.  
  255. CTree CTree::operator +(CTree &cOther)
  256. {
  257.         CTree c_newTree;
  258.         if (_root == nullptr)
  259.         {
  260.                 if (cOther._root != nullptr)
  261.                 {
  262.                         c_newTree = cOther;
  263.                         c_newTree._variables = cOther._variables;
  264.                 }
  265.         }
  266.         else if (cOther._root != nullptr)
  267.         {
  268.                 c_newTree = *this;
  269.                 CNode* pc_currentNode = c_newTree._root;
  270.                 if (pc_currentNode->_children == nullptr)
  271.                 {
  272.                         delete c_newTree._root;
  273.                         c_newTree._root = new CNode(*cOther._root);;
  274.                 }
  275.                 else
  276.                 {
  277.                         while ((*pc_currentNode->_children)->_maxChildren > 0)
  278.                         {
  279.                                 pc_currentNode = *pc_currentNode->_children;
  280.                         }
  281.                         c_newTree.DeleteIfWasVariable((*(pc_currentNode->_children))->_value);
  282.                         delete *(pc_currentNode->_children);
  283.                         *(pc_currentNode->_children) = new CNode(*cOther._root);;
  284.                 }
  285.  
  286.  
  287.                 for (int i = 0; i < cOther._variables.size(); i++)
  288.                 {
  289.                         c_newTree.AddIfNewVariable(cOther._variables.at(i));
  290.                 }
  291.         }
  292.         return c_newTree;
  293. }
  294.  
  295.  
  296. void CTree::operator =(CTree &cOther)
  297. {
  298.         _variables = cOther._variables;
  299.         if (_root != nullptr)
  300.         {
  301.                 delete _root;
  302.         }
  303.         _root = new CNode(*cOther._root);
  304. }
  305.  
  306. vector<string>& CTree::vctrGetVariableVector()
  307. {
  308.         return _variables;
  309. }
  310.  
  311. int CTree::BuildTree(vector<string> &vctrLoadedTokens)
  312. {
  313.         if (_root != nullptr)
  314.         {
  315.                 delete _root;
  316.                 _variables.clear();
  317.                 _root = nullptr;
  318.         }
  319.         return BuildSubTree(_root, vctrLoadedTokens);
  320. }
  321.  
  322. int CTree::BuildSubTree(CNode*& pcRootNode, vector<string> &vctrLoadedTokens)
  323. {
  324.         int i_errorCode = I_ERR_OK;
  325.         if (!vctrLoadedTokens.empty())
  326.         {
  327.                 pcRootNode = new CNode(vctrLoadedTokens.at(0));
  328.                 if (pcRootNode->e_type == CNode::variable)
  329.                 {
  330.                         AddIfNewVariable(pcRootNode->_value);
  331.                 }
  332.                 vctrLoadedTokens.erase(vctrLoadedTokens.begin());
  333.         }
  334.         else
  335.         {
  336.                 i_errorCode = I_ERR_INVALID_EXPRESSION;
  337.                 pcRootNode = new CNode(S_DEF_VAL);
  338.         }
  339.         for (; pcRootNode->_definedChildren < pcRootNode->_maxChildren; pcRootNode->_definedChildren++)
  340.         {
  341.                 i_errorCode = BuildSubTree(*(pcRootNode->_children + pcRootNode->_definedChildren), vctrLoadedTokens);
  342.         }
  343.         return i_errorCode;
  344. }
  345.  
  346. void CTree::AddIfNewVariable(string &sVariableName)
  347. {
  348.         bool bFound = false;
  349.         int i_varCount = _variables.size();
  350.         for (int i = 0; i < i_varCount && !bFound; i++)
  351.         {
  352.                 if (_variables.at(i) == sVariableName)
  353.                 {
  354.                         bFound = true;
  355.                 }
  356.         }
  357.         if (!bFound)
  358.         {
  359.                 _variables.push_back(sVariableName);
  360.         }
  361. }
  362.  
  363. void CTree::DeleteIfWasVariable(string &sVariableName)
  364. {
  365.         int i_varCount = _variables.size();
  366.         bool b_found = false;
  367.         for (int i = 0; i < i_varCount && !b_found; i++)
  368.         {
  369.                 if (_variables.at(i) == sVariableName)
  370.                 {
  371.                         _variables.erase(_variables.begin() + i);
  372.                         b_found = true;
  373.                 }
  374.         }
  375. }
  376.  
  377. string CTree::toString()
  378. {
  379.         if (_root != nullptr)
  380.         {
  381.                 return _root->toString();
  382.         }
  383. }
  384.  
  385. double CTree::Evaluate(vector<int> &vctrLoadedVariables, int &iErrorCode)
  386. {
  387.         if (_root == nullptr)
  388.         {
  389.                 return iErrorCode = I_ERR_EMPTY_TREE;
  390.         }
  391.         else
  392.         {
  393.                 iErrorCode = I_ERR_OK;
  394.                 return CalculateSubtree(_root, vctrLoadedVariables, iErrorCode);
  395.         }
  396. }
  397.  
  398. double CTree::CalculateSubtree(CNode *pcRootNode, vector<int> &vctrLoadedVariables, int &iErrorCode)
  399. {
  400.         if (iErrorCode == I_ERR_OK)
  401.         {
  402.                 switch (pcRootNode->e_type)
  403.                 {
  404.                 case CNode::value:
  405.                         return stoi(pcRootNode->_value);
  406.                 case CNode::variable:
  407.                         return ValueForVariable(pcRootNode->_value, vctrLoadedVariables);
  408.                 case CNode::op1arg:
  409.                         if (pcRootNode->_value == S_OP_SIN)
  410.                         {
  411.                                 return sin(CalculateSubtree(*pcRootNode->_children, vctrLoadedVariables, iErrorCode));
  412.                         }
  413.                         else if (pcRootNode->_value == S_OP_COS)
  414.                         {
  415.                                 return cos(CalculateSubtree(*pcRootNode->_children, vctrLoadedVariables, iErrorCode));
  416.                         }
  417.                 case CNode::op2arg:
  418.                         if (pcRootNode->_value == S_OP_ADD)
  419.                         {
  420.                                 return CalculateSubtree(*pcRootNode->_children, vctrLoadedVariables, iErrorCode) + CalculateSubtree(*(pcRootNode->_children + 1), vctrLoadedVariables, iErrorCode);
  421.                         }
  422.                         else if (pcRootNode->_value == S_OP_SUB)
  423.                         {
  424.                                 return CalculateSubtree(*pcRootNode->_children, vctrLoadedVariables, iErrorCode) - CalculateSubtree(*(pcRootNode->_children + 1), vctrLoadedVariables, iErrorCode);
  425.                         }
  426.                         else if (pcRootNode->_value == S_OP_MUL)
  427.                         {
  428.                                 return CalculateSubtree(*pcRootNode->_children, vctrLoadedVariables, iErrorCode) * CalculateSubtree(*(pcRootNode->_children + 1), vctrLoadedVariables, iErrorCode);
  429.                         }
  430.                         else if (pcRootNode->_value == S_OP_DIV)
  431.                         {
  432.                                 int i_divider = CalculateSubtree(*(pcRootNode->_children + 1), vctrLoadedVariables, iErrorCode);
  433.                                 if (i_divider == 0)
  434.                                 {
  435.                                         iErrorCode = I_ERR_DIV_BY_ZERO;
  436.                                         return stod(S_DEF_VAL);
  437.                                 }
  438.                                 else return CalculateSubtree(*pcRootNode->_children, vctrLoadedVariables, iErrorCode) / i_divider;
  439.                         }
  440.                         break;
  441.                 }
  442.         }
  443.         else
  444.         {
  445.                 return stod(S_DEF_VAL);
  446.         }
  447. }
  448.  
  449. int CTree::ValueForVariable(string sVarName, vector<int> &vctrLoadedVariables)
  450. {
  451.         bool b_isFound = false;
  452.         int i_varCount = (vctrLoadedVariables.size() < _variables.size()) ? vctrLoadedVariables.size() : _variables.size();
  453.         int i_value = 0;
  454.         for (int i = 0; i < i_varCount && !b_isFound; i++)
  455.         {
  456.                 if (_variables.at(i) == sVarName)
  457.                 {
  458.                         i_value = vctrLoadedVariables.at(i);
  459.                         b_isFound = true;
  460.                 }
  461.         }
  462.         return i_value;
  463. }
  464.  
  465.  
  466. #pragma once
  467. #include "CTree.h"
  468. #include <iostream>
  469. #include <string>
  470. #include <vector>
  471.  
  472. using namespace std;
  473.  
  474. #define S_CMD_ENTER "enter"
  475. #define S_CMD_VARS "vars"
  476. #define S_CMD_PRINT "print"
  477. #define S_CMD_COMP "comp"
  478. #define S_CMD_JOIN "join"
  479. #define S_CMD_EXIT "exit"
  480.  
  481. #define S_RESULT "result: "
  482. #define I_ERR_INVALID_ARGUMENT 5
  483. #define S_ERR_INVALID_ARGUMENT "Invalid argument!"
  484. #define I_ERR_NOT_ENOUGH_ARGUMENTS 6
  485. #define S_ERR_NOT_ENOUGH_ARGUMENTS "Not enough arguments!"
  486. #define I_ERR_TOO_MANY_ARGUMENTS 7
  487. #define S_ERR_TOO_MANY_ARGUMENTS "Too many arguments!"
  488. #define I_ERR_UNRECOGNISED_COMMAND 8
  489. #define S_ERR_UNRECOGNISED_COMMAND "Unrecognised command!"
  490. #define I_END_PROGRAM -1
  491.  
  492. class CInterFace
  493. {
  494. public:
  495.         CInterFace();
  496.         ~CInterFace();
  497.         int iGetAndExecuteCommand();
  498.         int iProceedJoin();
  499.         vector<string> vctr_loadedTokens;
  500.  
  501.  
  502. private:
  503.         void vSplit(vector<string> &result, string str, char delim);
  504.         int iProceedEnter();
  505.         int iProceedVars();
  506.         int iProceedPrint();
  507.         int iProceedComp();
  508.         int iProceedExit();
  509.         bool bIsAnPositiveInteger(string sStr);
  510.  
  511.         CTree c_tree;
  512. };
  513.  
  514.  
  515. #include "stdafx.h"
  516. #include "CInterFace.h"
  517.  
  518. CInterFace::CInterFace()
  519. {
  520. }
  521.  
  522. CInterFace::~CInterFace()
  523. {
  524. }
  525.  
  526. int CInterFace::iGetAndExecuteCommand()
  527. {
  528.         cin.clear();
  529.  
  530.         string s_Line;
  531.         getline(cin, s_Line);
  532.         vSplit(vctr_loadedTokens, s_Line, ' ');
  533.  
  534.         int i_errorCode;
  535.         string s_command = vctr_loadedTokens.at(0);
  536.         vctr_loadedTokens.erase(vctr_loadedTokens.begin());
  537.  
  538.         if (s_command == S_CMD_ENTER)
  539.         {
  540.                 i_errorCode = iProceedEnter();
  541.         }
  542.         else if (s_command == S_CMD_VARS)
  543.         {
  544.                 i_errorCode = iProceedVars();
  545.         }
  546.         else if (s_command == S_CMD_PRINT)
  547.         {
  548.                 i_errorCode = iProceedPrint();
  549.         }
  550.         else if (s_command == S_CMD_COMP)
  551.         {
  552.                 i_errorCode = iProceedComp();
  553.         }
  554.         else if (s_command == S_CMD_JOIN)
  555.         {
  556.                 i_errorCode = iProceedJoin();
  557.         }
  558.         else if (s_command == S_CMD_EXIT)
  559.         {
  560.                 i_errorCode = iProceedExit();
  561.         }
  562.         else
  563.         {
  564.                 i_errorCode = I_ERR_UNRECOGNISED_COMMAND;
  565.         }
  566.         switch (i_errorCode)
  567.         {
  568.         case I_ERR_VAR_WITH_INVALID_CHAR: cout << S_ERR_VAR_WITH_INVALID_CHAR << S_UNDEFINED << endl; break;
  569.         case I_ERR_EMPTY_TREE: cout << S_ERR_EMPTY_TREE << endl; break;
  570.         case I_ERR_DIV_BY_ZERO: cout << S_ERR_DIV_BY_ZERO << endl; break;
  571.         case I_ERR_INVALID_EXPRESSION: cout << S_ERR_IVALID_EXPRESSION << c_tree.toString() << endl; break;
  572.         case I_ERR_INVALID_ARGUMENT: cout << S_ERR_INVALID_ARGUMENT << endl; break;
  573.         case I_ERR_NOT_ENOUGH_ARGUMENTS: cout << S_ERR_NOT_ENOUGH_ARGUMENTS << endl; break;
  574.         case I_ERR_TOO_MANY_ARGUMENTS: cout << S_ERR_TOO_MANY_ARGUMENTS << endl; break;
  575.         case I_ERR_UNRECOGNISED_COMMAND: cout << S_ERR_UNRECOGNISED_COMMAND << endl; break;
  576.         }
  577.         return i_errorCode;
  578. }
  579.  
  580. void CInterFace::vSplit(vector<string> &result, string str, char delim)
  581. {
  582.         string tmp = "";
  583.         result.clear();
  584.  
  585.         for (string::iterator i = str.begin(); i < str.end(); ++i)
  586.         {
  587.                 if ((const char)*i != delim  && i != str.end())
  588.                 {
  589.                         tmp += *i;
  590.                 }
  591.                 else
  592.                 {
  593.                         if (tmp != "")
  594.                         {
  595.                                 result.push_back(tmp);
  596.                         }
  597.                         tmp = "";
  598.                 }
  599.         }
  600.         if (tmp != "")
  601.         {
  602.                 result.push_back(tmp);
  603.         }
  604. }
  605.  
  606. int CInterFace::iProceedEnter()
  607. {
  608.         return c_tree.BuildTree(vctr_loadedTokens);
  609. }
  610.  
  611. int CInterFace::iProceedVars()
  612. {
  613.         if (vctr_loadedTokens.empty())
  614.         {
  615.                 int i_varCount = c_tree.vctrGetVariableVector().size();
  616.                 for (int i = 0; i < i_varCount; i++)
  617.                 {
  618.                         cout << c_tree.vctrGetVariableVector().at(i) << "\t";
  619.                 }
  620.                 cout << endl;
  621.                 return I_ERR_OK;
  622.         }
  623.         else
  624.         {
  625.                 return I_ERR_TOO_MANY_ARGUMENTS;
  626.         }
  627. }
  628.  
  629.  
  630. int CInterFace::iProceedPrint()
  631. {
  632.         if (vctr_loadedTokens.empty())
  633.         {
  634.                 cout << c_tree.toString() << endl;
  635.                 return I_ERR_OK;
  636.         }
  637.         else
  638.         {
  639.                 return I_ERR_TOO_MANY_ARGUMENTS;
  640.         }
  641. }
  642.  
  643. int CInterFace::iProceedComp()
  644. {
  645.         int i_varsCount = c_tree.vctrGetVariableVector().size();
  646.         int i_tokensCount = vctr_loadedTokens.size();
  647.         if (i_tokensCount > i_varsCount) { return I_ERR_TOO_MANY_ARGUMENTS; }
  648.         if (i_tokensCount < i_varsCount) { return I_ERR_NOT_ENOUGH_ARGUMENTS; }
  649.         bool b_argsCorrect = true;
  650.         vector<int> vctr_loadedVars;
  651.         string sActToken;
  652.         for (int i = 0; i < i_tokensCount && b_argsCorrect; i++)
  653.         {
  654.                 sActToken = vctr_loadedTokens.at(i);
  655.                 if (bIsAnPositiveInteger(sActToken))
  656.                 {
  657.                         vctr_loadedVars.emplace_back(stoi(sActToken));
  658.                 }
  659.                 else
  660.                 {
  661.                         b_argsCorrect = false;
  662.                 }
  663.         }
  664.         if (!b_argsCorrect)
  665.         {
  666.                 return I_ERR_INVALID_ARGUMENT;
  667.         }
  668.         int i_errCode = I_ERR_OK;
  669.         double d_potResult = c_tree.Evaluate(vctr_loadedVars, i_errCode);
  670.         if (i_errCode == I_ERR_OK)
  671.         {
  672.                 cout << S_RESULT << d_potResult << endl;
  673.         }
  674.         return i_errCode;
  675. }
  676.  
  677. int CInterFace::iProceedJoin()
  678. {
  679.         CTree newTree;
  680.         int i_errorCode = newTree.BuildTree(vctr_loadedTokens);
  681.         c_tree = c_tree + newTree;
  682.         return i_errorCode;
  683. }
  684.  
  685. int CInterFace::iProceedExit()
  686. {
  687.         return I_END_PROGRAM;
  688. }
  689.  
  690. bool CInterFace::bIsAnPositiveInteger(string sStr)
  691. {
  692.         return (sStr.find_first_not_of("0123456789") == std::string::npos) && stoi(sStr) > 0;
  693. }