Advertisement
pablo7890

MathParser Beta

Apr 23rd, 2013
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.00 KB | None | 0 0
  1. //#pragma once
  2. #include <iostream>
  3. #include <string>
  4. #include <cmath>
  5. #include <cstdio>
  6. #include <cstdlib>
  7.  
  8. using namespace std;
  9.  
  10. ///////////////////
  11. int potega(int liczba , int potega )
  12. {
  13.     int wynik = liczba;
  14.     for(int i=1;i<potega;i++)
  15.     {
  16.         wynik = wynik * liczba;
  17.     }
  18.     return wynik;
  19. }
  20. ///////////////////
  21. //////
  22. //////
  23. //////
  24. class Stos
  25. {
  26.     private:
  27.          int *tab;              // dynamiczna tablica do przechowywania danych
  28.          long size;             // ilosc elementow, ktore moze pomiescic stos
  29.          long last;             // numer elementu na gorze stosu
  30.          long Numbers;          // liczba elementow na stosie
  31.          
  32.     public:
  33.         Stos(void);
  34.         Stos(long lSize);
  35.         void Push(int elem);
  36.         int Pop();
  37.         const int& Top();
  38.         void GrowStack();
  39.         long GetNumbers();
  40.     public:
  41.         ~Stos(void);
  42. };
  43. class Calc
  44. {
  45.     private:
  46.         string line;
  47.         string result;
  48.         string operation;
  49.         string oper;
  50.         int ilLiczb;
  51.         int ilZnakow;
  52.         string ex;
  53.        
  54.     public:
  55.         Calc();
  56.         int RPN(string operation);
  57.         int Result(string operation);
  58.         ~Calc(void);
  59. };
  60. //////////////////////////////////
  61. Stos::Stos(void)
  62. {
  63.                                 // konstruktor domyslny
  64.     last = 0;                   // pusty stos
  65.     size = 20;                  // ilosc elementow, ktore stos moze pomiescic
  66.     Numbers = 0;
  67.  
  68.     tab = new int[size];        // przydzielamy dynamicznie pamiec
  69.  
  70.     if(tab == NULL)             // blad przy alokacji pamieci
  71.     {
  72.          throw "Blad alokcacji pamieci!";     // wyjatek
  73.     }
  74.  
  75.    
  76. }
  77.  
  78. Stos::Stos(long lSize)
  79. {
  80.                                 // konstruktor parametryczny
  81.     last = 0;                   // pusty stos
  82.     size = lSize;               // ilosc elementow, ktore stos moze pomiescic
  83.     Numbers = 0;
  84.  
  85.     tab = new int[size];        // przydzielamy dynamicznie pamiec
  86.  
  87.     if(tab == NULL)             // blad przy alokacji pamieci
  88.     {
  89.         throw "Blad alokcacji pamieci!";     // wyjatek
  90.     }
  91. }
  92.  
  93. void Stos::Push(int elem)
  94. {
  95.     if(last < size)             // sprawdzamy czy na stosie jest miejsce
  96.     {
  97.         tab[last ++] = elem;        // umieszczamy element na gorze stosu
  98.         Numbers ++;
  99.     }
  100.     else
  101.     {
  102.         GrowStack();            // powiekszamy stos
  103.     }
  104. }
  105.  
  106. int Stos::Pop()
  107. {
  108.     if(last >= 0)                       // sprawdzamy czy na stosie jest jakis element
  109.     {
  110.         Numbers --;
  111.         return tab[--last];             // zdejmujemy element ze stosu
  112.     }
  113. }
  114.  
  115. const int& Stos::Top()
  116. {
  117.     return tab[last - 1];           // pokazuje element, ktory jest na szczycie stosu
  118. }
  119.  
  120. void Stos::GrowStack()
  121. {
  122.     int *newTab = new int[size + 10];                   // powiekszamy nowa tablice o 10 elementow
  123.  
  124.     for(int i=0; i < size; i++)
  125.         newTab[i] = tab[i];                             // przekopiowujemy zawartosc starej tablicy do nowej
  126.         delete []tab;                                   // kasujemy stara tablice
  127.  
  128.         tab = newTab;                                   // przypisujemy nowa tablice jako "stara"
  129.  
  130.         size += 10;                                     // zmieniamy wielkosc tablicy na aktualna
  131. }
  132.  
  133. long Stos::GetNumbers()
  134. {
  135.     return Numbers;
  136. }
  137.  
  138. Stos::~Stos(void)
  139. {
  140.     delete []tab;               // zwalniamy zajeta pamiec
  141. }
  142. ////////////////////////
  143. Calc::Calc()
  144. {
  145.     result = "";
  146.     operation = "";
  147.     ilLiczb = 0;
  148.     ilZnakow = 0;
  149.    
  150. }
  151.  
  152. int Calc::RPN(string operation)
  153. {
  154.     Stos *stack = new Stos;
  155.     result = "";
  156.     ilLiczb=0;
  157.     ilZnakow=0;
  158.     for(int i=0; i < operation.size(); i++)
  159.     {
  160.        
  161.        
  162.             if ((operation[i] >= '0' && operation[i] <= '9')) {         // sprawdzamy czy pierwszy element jest liczba
  163.                 result += operation[i];
  164.                 if (!(operation[i+1] >= '0' && operation[i+1] <= '9')) {        // sprawdzamy czy kolejny element nie jest liczba i dodajemy spacje
  165.                     result += " ";
  166.                     ilLiczb++;
  167.                 }
  168.             }
  169.             else if (operation[i] == '*' || operation[i] == '/' || operation[i] == '-'|| operation[i] == '+' || operation[i] == '^')
  170.             {
  171.                
  172.                 if(stack->Top()==NULL)
  173.                 {
  174.                     stack->Push((int)operation[i]);
  175.                     ilZnakow++;
  176.                 }
  177.                 else
  178.                 {
  179.                     char x = operation[i];
  180.                     char y = stack->Pop();
  181.                    
  182.                     if((y == '*' || y == '/') || ((y == '+' || y == '-') && x != '*' && x != '/'))
  183.                     {
  184.                         result += y;
  185.                         result += " ";
  186.                         while(stack->GetNumbers()>0)
  187.                         {
  188.                             result += stack->Pop();
  189.                             result += " ";
  190.                         }
  191.                        
  192.                         stack->Push(x);
  193.                     }
  194.                     else
  195.                     {
  196.                         stack->Push(y);
  197.                         stack->Push(x);
  198.                     }
  199.                     ilZnakow++;
  200.                 }
  201.                
  202.             }
  203.             else
  204.             {
  205.                 if(operation[i] != ' ')
  206.                 {
  207.                     ex = "Wystapily niepoprane znaki w wyrazeniu (np. litery)!";
  208.                     throw ex;
  209.                 }
  210.             }
  211.         }
  212.     while(stack->GetNumbers()>0)
  213.     {
  214.         result += stack->Pop();
  215.         result += " ";
  216.     }
  217.         //cout << ilLiczb << "test" << ilZnakow;
  218.     if(ilLiczb != ilZnakow + 1)
  219.     {
  220.         ex = "Niepoprawne wyrazenie (ilosc znakow musi byc o jeden mniejsza od ilosci liczb) ";
  221.         throw ex;
  222.     }
  223.     //cout << result << endl;
  224.     return Result(result);
  225.    
  226. }
  227.  
  228. int Calc::Result(string operation)
  229. {
  230.    
  231.     Stos *stack2 = new Stos;
  232.     stack2->Pop();
  233.     int op;
  234.     int op2;
  235.     string res;
  236.     //cout << "t" << operation.size();
  237.     for(int i=0; i < operation.size(); i++)
  238.     {
  239.         res = "";
  240.         int k = 200;
  241.  
  242.         //cout << "i" << i;
  243.         //cout << stack2->Top() << endl;
  244.        
  245.         switch (operation[i])
  246.         {
  247.         case '0':
  248.            
  249.         case '1':
  250.            
  251.         case '2':
  252.            
  253.         case '3':
  254.            
  255.         case '4':
  256.            
  257.         case '5':
  258.            
  259.         case '6':
  260.            
  261.         case '7':
  262.            
  263.         case '8':
  264.            
  265.         case '9':
  266.             res = operation[i];
  267.             stack2->Push(atoi(res.c_str()));
  268.             break;
  269.  
  270.         case '*':
  271.             op2 = stack2->Pop() * stack2->Pop();
  272.             stack2->Push(op2);
  273.             break;
  274.  
  275.         case '/':
  276.             op2 = stack2->Pop();  
  277.                 if (op2 != 0)
  278.                 {
  279.                     op = stack2->Pop() / op2;
  280.                     stack2->Push(op);
  281.                 }
  282.                 else {
  283.                     cout << "Blad dzielenia przez zero!" << endl;
  284.                    
  285.                 }
  286.             break;
  287.  
  288.         case '+':
  289.             op2 = stack2->Pop() + stack2->Pop();
  290.             stack2->Push(op2);
  291.             break;
  292.  
  293.         case '^':
  294.             op2 = potega(stack2->Pop(), stack2->Pop());
  295.             stack2->Push(op2);
  296.             break;
  297.  
  298.         case ' ':
  299.             break;
  300.  
  301.         case '-':
  302.            op2 = stack2->Pop();
  303.            op = stack2->Pop() - op2;
  304.            stack2->Push(op);
  305.            break;
  306.  
  307.         default:
  308.            cout << "Blad - nieznany znak!" << endl;
  309.            
  310.  
  311.         }
  312.     }
  313.    
  314.    
  315.     //cout << "Wynik wyrazenia: " <<endl;
  316.     //cout << stack2->Pop() << endl;
  317.     return stack2->Pop();
  318. }
  319.  
  320. Calc::~Calc(void)
  321. {
  322. }
  323. //////
  324. ////// te wszystkie klasy można by walnac w jakims includzie, ale skoro jeden plik ma byc.... xd
  325. //////
  326.  
  327.  
  328. void parser();
  329. int error();
  330. bool sprawdz_nawiasy();
  331.  
  332. //   zmienne
  333.  
  334. string input;
  335.  
  336. //   -------
  337.  
  338. int main()
  339. {
  340.     int n;
  341.     cin >> n;
  342.     for (int i=0; i<n; i++)
  343.     {
  344.         parser();
  345.     }
  346. }
  347.  
  348. int error()
  349. {
  350.     cout << "error";
  351. //  exit(EXIT_FAILURE);
  352. }
  353.  
  354. void parser()
  355. {
  356.     Calc Wynik;
  357.     string x,y;
  358.    
  359.     const char* pi = "3.141592653589";
  360.     const char* e = "2.7182818285";
  361.    
  362.     cin >> input >> x >> y;
  363.    
  364.     //wstaw do stringa odpowiednie liczby pod x i y oraz pi i e
  365.    
  366.     input.replace(input.find('x'),1,x);
  367.     input.replace(input.find('y'),1,y);
  368.  
  369. //  input.replace(input.find('pi'),1,pi);
  370. //  input.replace(input.find('e'),1,e);
  371.    
  372.     //---------------------------------------------
  373.    
  374.     if (sprawdz_nawiasy()==false)
  375.     {
  376.         error();
  377.     }
  378.     else
  379.     {
  380.         ///
  381.         string func,wyrazenie,zamiana;
  382.         for (int i=0; i<input.length(); i++)
  383.         {
  384.             if (input[i] == '(' && !isdigit(input[i-1]))
  385.             {
  386.                 for (int j=5; j>0; j--)
  387.                 {
  388.                     if (!isdigit(input[i-j]))
  389.                     {
  390.                         func += input[i-j];
  391.                     }
  392.                 }
  393.                 int k=0;
  394.                 while (input[i+k]==')')
  395.                 {
  396.                     wyrazenie += input[i+k];
  397.                     k++;
  398.                 }
  399.                 zamiana += func;
  400.                 zamiana += "(";
  401.                 zamiana += wyrazenie;
  402.                 zamiana += ")";
  403.                 if (func == "abs")
  404.                 {
  405.                     input.replace(input.find(zamiana),1,abs(Wynik.RPN(wyrazenie)));
  406.                 }
  407.                 // pozostalwe funkcje sie wklei jak pierwsza bedzie dzialac
  408.             }
  409.         }
  410.         ///
  411.     }
  412. }
  413.  
  414. bool sprawdz_nawiasy()
  415. {
  416.     int nawiasy=0;
  417.     for (int i=0; i<input.length(); i++)
  418.     {
  419.         if (input[i] == '(')
  420.         {
  421.             nawiasy++;
  422.         }
  423.         else if (input[i] == ')')
  424.         {
  425.             nawiasy--;
  426.             if (nawiasy < 0)
  427.             {
  428.                 error();
  429.             }
  430.         }
  431.     }
  432.  
  433.     if (nawiasy!=0)
  434.     {
  435.         return false;
  436.     }
  437.     else
  438.     {
  439.         return true;
  440.     }
  441. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement