Advertisement
Guest User

calculator

a guest
Dec 13th, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.89 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <algorithm>
  5. #include <exception>
  6. #include <stdexcept>
  7. #include <cctype>
  8. #include <cmath>
  9.  
  10. enum AnalysType // lul c tellement trop genial
  11. {
  12.     PLUS,
  13.     MOINS,
  14.     FOIX,
  15.     DIV,
  16.     LPARENT,
  17.     RPARENT,
  18.     NUM,
  19.     POW
  20. };
  21.  
  22. std::ostream& operator<<(std::ostream& output, AnalysType value)
  23. {
  24.     switch(value)
  25.     {
  26.     case PLUS:
  27.         output << "PLUS";
  28.         break;
  29.     case MOINS:
  30.         output << "MOINS";
  31.         break;
  32.     case FOIX:
  33.         output << "FOIX";
  34.         break;
  35.     case DIV:
  36.         output << "DIV";
  37.         break;
  38.     case LPARENT:
  39.         output << "LPARENT";
  40.         break;
  41.     case RPARENT:
  42.         output << "RPARENT";
  43.         break;
  44.     case NUM:
  45.         output << "NUM";
  46.         break;
  47.     case POW:
  48.         output << "POW";
  49.         break;
  50.     }
  51. }
  52.  
  53. template <typename T>
  54. std::ostream& operator<<(std::ostream& output, std::vector<T> vect)
  55. {
  56.     for_each(vect.begin(), vect.end(), [&output](T value) -> void
  57.     {
  58.        output << value << "  ";
  59.     });
  60.    
  61.     return output;
  62.    
  63. }
  64.  
  65. bool goodNbrParentesis(std::vector<AnalysType> listType, bool& thereAreOne)
  66. {
  67.     int ouvrantes {0};
  68.     int fermantes {0};
  69.     for(AnalysType caractere: listType)
  70.     {
  71.         if(caractere == LPARENT)
  72.         {
  73.             ++ouvrantes;
  74.             thereAreOne = true;
  75.         }
  76.         else if(caractere == RPARENT)
  77.         {
  78.             ++fermantes;
  79.         }
  80.    
  81.         if(fermantes > ouvrantes)
  82.         {
  83.             // Pas la peine de continuer, l'expression est invalide.
  84.             return false;
  85.         }
  86.     }
  87.  
  88.     return ouvrantes == fermantes;
  89. }
  90.  
  91.  
  92. std::vector<AnalysType>::iterator right_parentesis_to_cut(std::vector<AnalysType> a)
  93. {
  94.     int nbrOpenNonClose = 0;
  95.  
  96.     for (std::vector<AnalysType>::iterator i{ a.begin() }; i != a.end(); i++)
  97.     {
  98.  
  99.         if (*i == RPARENT && nbrOpenNonClose == 0)
  100.         {
  101.             return i;
  102.         }
  103.  
  104.         switch (*i)
  105.         {
  106.         case LPARENT:
  107.             nbrOpenNonClose++;
  108.             break;
  109.         case RPARENT:
  110.             nbrOpenNonClose--;
  111.             break;
  112.         }
  113.     }
  114.  
  115.     return a.end();
  116.    
  117. }
  118.  
  119. std::vector<double> split_ends(const std::vector<double>& source, const std::vector<int>& ends) {
  120.     std::vector<std::vector<double>> result;
  121.     result.reserve(ends.size());
  122.     auto anchor_front = source.begin();
  123.     for (auto one_end: ends) {
  124.         auto anchor_end = std::next(source.begin(), one_end + 1);
  125.         result.emplace_back(anchor_front, anchor_end);
  126.         anchor_front = anchor_end;
  127.     }
  128.  
  129.     return result[1];
  130. }
  131.  
  132. std::vector<double>::iterator indicesToIterator(std::vector<double> truc, int indice)
  133. {
  134.     if(indice >= truc.size())
  135.     {
  136.         throw std::runtime_error("Nan mais tu me prends pour un con Connard.");
  137.     }
  138.    
  139.     int iNbr = 0;
  140.    
  141.     for(std::vector<double>::iterator i {truc.begin()} ; i != truc.end() ; i++)
  142.     {
  143.         if(iNbr == indice)
  144.         {
  145.             return i;
  146.         }
  147.        
  148.         iNbr++;
  149.     }
  150.    
  151.     return truc.end();
  152. }
  153.  
  154. template <typename T>
  155. std::vector<T> insert(typename std::vector<T>::iterator ItFirstPart1, typename std::vector<T>::iterator ItSecondPart1, T const& value,
  156.                       typename std::vector<T>::iterator ItFirstPart2, typename std::vector<T>::iterator ItSecondPart2)
  157. {
  158.     std::vector<T> BigVect {ItFirstPart1, ItSecondPart1};
  159.          
  160.     BigVect.push_back(value);
  161.          
  162.     BigVect.insert( BigVect.end(), ItFirstPart2, ItSecondPart2 );
  163.      
  164.     return BigVect;
  165. }
  166.  
  167. double process(std::vector<double> listNbr, std::vector<AnalysType> listType);
  168. //For using that later
  169.  
  170. void analysIfParentesis(std::vector<double>& listNbr, std::vector<AnalysType>& listType)
  171. {
  172.     bool thereAreOneP{ false };
  173.  
  174.     if (!goodNbrParentesis(listType, thereAreOneP))
  175.     {
  176.         throw std::runtime_error("Why god send to me someone who don't know how to count parentesis ?\nI really hate my life.");
  177.     }
  178.     else if (thereAreOneP)
  179.     {
  180.         std::vector<AnalysType> to_send{ std::find(listType.begin(), listType.end(), LPARENT),
  181.                                          right_parentesis_to_cut(listType)};
  182.                                          
  183.         int nbr{ static_cast<int>(std::count(std::begin(listType), std::find(listType.begin(), listType.end(), LPARENT), NUM) )};
  184.  
  185.         int nbrBack{ static_cast<int>( std::count(listType.begin(), right_parentesis_to_cut(listType), NUM) )};
  186.        
  187.         std::vector<double> nbr_to_send { split_ends(listNbr, std::vector<int> {nbr, nbrBack}) };
  188.  
  189.         double result = process(nbr_to_send, to_send);
  190.        
  191.         listNbr = insert(listNbr.begin(), indicesToIterator(listNbr, nbr - 1), result,
  192.                          indicesToIterator(listNbr, nbrBack), listNbr.end());
  193.        
  194.         listType = insert(listType.begin(), std::find(listType.begin(), listType.end(), LPARENT), NUM,
  195.                           right_parentesis_to_cut(listType)++, listType.end());
  196.     }
  197. }
  198.  
  199. double operator_use(double nb1, AnalysType op, double nb2)
  200. {
  201.     switch(op)
  202.     {
  203.     case PlUS:
  204.         return nb1 + nb2;
  205.     case MOINS:
  206.         return nb1 - nb2;
  207.     case FOIX:
  208.         return nb1 * nb2;
  209.     case DIV:
  210.         return nb1 / nb2;
  211.     case POW:
  212.         return pow(nb1, nb2);
  213.     }
  214. }
  215.  
  216. void calcul(std::vector<double> listNbr, std::vector<AnalysType> listType, std::vector<AnalysType>::iterator it)
  217. {
  218.     if(!( (*(it - 1)) == NUM) && (*(it + 1)) == NUM) )
  219.     {
  220.         throw std::runtime_error("Syntax error.");
  221.     }
  222.    
  223.     result = operator_use(*(it - 1), *it, *(it + 1));
  224. }
  225.  
  226. double process(std::vector<double> listNbr, std::vector<AnalysType> listType)
  227. {
  228.     analysIfParentesis(listNbr, listType);
  229.    
  230.     for(std::vector<AnalysType>::iterator i{listType.begin()} ; i != listType.end() ; i++)
  231.     {
  232.         i = std::find(i, listType.end(), POW);
  233.        
  234.         if(i == listType.end())
  235.         {
  236.             break;
  237.         }
  238.        
  239.        
  240.     }
  241.    
  242.     return 666;
  243. }
  244.  
  245. bool if_Isdigitandpoint(char a)
  246. {
  247.     if (isdigit(a) || a == '.')
  248.     {
  249.         return true;
  250.     }
  251.     else
  252.     {
  253.         return false;
  254.     }
  255. }
  256.  
  257. double analyseEntry(std::string entry)
  258. {
  259.     std::vector<double> listNbr;
  260.     std::vector<AnalysType> listType;
  261.  
  262.     for (std::string::iterator i{ std::begin(entry) }; i != std::end(entry); )
  263.     {
  264.         if (isdigit(*i) || *i == '.')
  265.         {
  266.             std::string::iterator it_first_space{ std::find_if_not(i, std::end(entry), if_Isdigitandpoint ) };
  267.  
  268.             std::string mot{ i, it_first_space };
  269.  
  270.             std::string::size_type sz;
  271.             double nbr{ stod(mot, &sz) };
  272.  
  273.             listNbr.push_back(nbr);
  274.  
  275.             listType.push_back(NUM);
  276.  
  277.             i = it_first_space;
  278.         }
  279.         else if (ispunct(*i) && *i != '.')
  280.         {
  281.             switch (*i)
  282.             {
  283.             case '+':
  284.                 listType.push_back(PLUS);
  285.                 break;
  286.             case '-':
  287.                 listType.push_back(MOINS);
  288.                 break;
  289.             case '*':
  290.                 listType.push_back(FOIX);
  291.                 break;
  292.             case '/':
  293.                 listType.push_back(DIV);
  294.                 break;
  295.             case '(':
  296.                 listType.push_back(LPARENT);
  297.                 break;
  298.             case ')':
  299.                 listType.push_back(RPARENT);
  300.                 break;
  301.             case '^':
  302.                 listType.push_back(POW);
  303.                 break;
  304.             default:
  305.                 throw std::runtime_error("Your operator is just some boolshit. thanks for coming.");
  306.                 break;
  307.             }
  308.             i++;
  309.         }
  310.         else if (isspace(*i))
  311.         {
  312.             i = std::find_if_not(i, std::end(entry), isspace);
  313.             //find the first non-space character
  314.         }
  315.         else if (isalpha(*i))
  316.         {
  317.             throw std::runtime_error("DON'T PUT LETTERS. Thanks.");
  318.         }
  319.         else if(*i == '\0')
  320.         {
  321.             std::cout << "prut" << std::endl;
  322.             break;
  323.         }
  324.         else
  325.         {
  326.             throw std::runtime_error("Shit, it's me this time.");
  327.         }
  328.     }
  329.    
  330.     std::cout << listNbr << std::endl << listType << std::endl;
  331.  
  332.     return process(listNbr, listType);
  333. }
  334.  
  335. int main()
  336. {
  337.     bool continuer{ true };
  338.  
  339.  
  340.     while (continuer)
  341.     {
  342.         std::string entry;
  343.  
  344.         std::cout << "> ";
  345.  
  346.         std::getline(std::cin, entry);
  347.  
  348.         try
  349.         {
  350.             std::cout << analyseEntry(entry) << std::endl;
  351.         }
  352.         catch (const std::exception& e)
  353.         {
  354.             std::cout << "error : " << e.what() << std::endl;
  355.         }
  356.     }
  357.  
  358.     return 0;
  359. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement