Advertisement
Guest User

Untitled

a guest
Jun 29th, 2016
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.37 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <list>
  4. #include <stack>
  5. #include <sstream>
  6. #include <vector>
  7. #include <cmath>
  8.  
  9. using namespace std;
  10.  
  11. class exprFilter{                // Базовый класс для работы с выражениями
  12. protected:
  13.     list <string> express;       // Список для выражения
  14. private:
  15.     void show(){                                             // Вывод списка выражений
  16.         list<string>::iterator it = this->express.begin();   // Введем итератор it как начало списка
  17.         for (it; it != this->express.end(); it++)            // Выводим список
  18.         {
  19.             cout << *it << ' ';
  20.         }
  21.         cout << endl;
  22.     }
  23.     // взятие приоритета операции
  24.     // вернёт -1, если char не является операцией
  25.     int priority(char &c){
  26.         // символ & используется для того, чтобы создать копию объекта
  27.         switch (c)
  28.         {
  29.             case '(':
  30.             case ')':
  31.                 return 0;
  32.             case '+': case '-':
  33.                 return 1;
  34.             case '*': case '/':
  35.                 return 2;
  36.             case '^':
  37.                 return 3;
  38.             default:
  39.                 return -1;
  40.         }
  41.     }
  42. public:
  43.     exprFilter(string &line){
  44.         // Фильтр выражений, используемый для того, чтобы правильно обрабатывать данные,
  45.         // подаваемые в исходной строке
  46.         cout << line << endl;
  47.         stringstream in;
  48.         in << line;
  49.         // Посимвольная фильтрация потока (строки)
  50.         char c = ' '; line = "";
  51.         while (in >> c)
  52.         {
  53.             if (priority(c) != -1)                           // Т.е. принята операция или скобка
  54.             {
  55.                 // Если в буфере уже что-либо записано
  56.                 if (line != "")
  57.                 {
  58.                     // то выбрасываем записанный элемент из буфера в очередь
  59.                     this->express.push_back(line);
  60.                     // и обнуляем
  61.                     line = "";
  62.                 }
  63.                 // переводим переменную c в string и бросаем в очередь
  64.                 line += c;
  65.                 this->express.push_back(line);
  66.                 // снова обнуляем
  67.                 line = "";
  68.             }
  69.             else // Если принят операнд
  70.             {
  71.                 line += c;
  72.             }
  73.         }
  74.         if (line != "") // Если же string не пуст
  75.         this->express.push_back(line);   // Добавляем в конец списка элемент
  76.         this->show();   // Выводит результат работы конструктора
  77.     }
  78. };
  79. class exprPolish : public exprFilter{
  80.     // Класс для работы с переводом выражения из инфиксной формы записи в ОПН
  81. protected:
  82.     float param;    // Параметр
  83.     bool isTrig(string &oper)
  84.     {
  85.     // Функция, предназначенная для восприятия математических выражений в программе
  86.         return (oper == "sin" || oper == "cos" || oper == "tan" || oper == "asin"
  87.                 || oper == "acos" || oper == "atan" || oper == "sinh" || oper == "log"
  88.                 || oper == "cosh" || oper == "tanh" || oper == "atanh" || oper == "sqrt");
  89.     }
  90.     // Взятие приоритета операции
  91.     // вернёт -1, если string не является операцией
  92.     int priority(string &s)
  93.     {
  94.         if (isTrig(s))  // Если математические выражения
  95.             return -2;
  96.         if (s.length() > 1) //?
  97.             return -1;
  98.         switch (s[0])   //?
  99.         {
  100.             case '(':
  101.             case ')':
  102.                 return 0;
  103.             case '+': case '-':
  104.                 return 1;
  105.             case '*': case '/':
  106.                 return 2;
  107.             case '^':
  108.                 return 3;
  109.             default:
  110.                 return -1;
  111.         }
  112.     }
  113.     /*
  114.      * подаются копии, т.к. в Expression::getResult()
  115.      * используются аргументы от stof(string);
  116.     */
  117.     float power(float z, float c)
  118.     {
  119.         // Функция возведения в степень и различные ситуации
  120.         if (c == 0)
  121.             return 1;
  122.         if (c == 1)
  123.             return z;
  124.         float result;
  125.         if (c < 0)
  126.         {
  127.             c = abs(c);
  128.             z = 1/z;
  129.         }
  130.         result = z;
  131.        
  132.         for (unsigned int k = 1; k < c; k++) //?
  133.         {
  134.             result *= z;
  135.         }
  136.         return result;
  137.     }
  138.    
  139.     void getTrigResult(string &oper, string &right, list<string> &LST)
  140.     {
  141.         // Суть: в данном методе просматривается выражение, и если окажется,
  142.         // что выражение - тригонометрическая функция от параметра икс,
  143.         // то правильно ее обработает и поместит в начало списка LST
  144.         float z = getValue(right); // где z - тригонометрическая функция от икс
  145.        
  146.         if (oper == "sin")
  147.             z = sin(z);
  148.         else if (oper == "cos")
  149.             z = cos(z);
  150.         else if (oper == "tan")
  151.             z = tan(z);
  152.         else if (oper == "atan")
  153.             z = atan(z);
  154.         else if (oper == "asin")
  155.             z = asin(z);
  156.         else if (oper == "acos")
  157.             z = acos(z);
  158.         else if (oper == "cosh")
  159.             z = cosh(z);           
  160.         else if (oper == "sinh")
  161.             z = sinh(z);
  162.         else if (oper == "acosh")
  163.             z = acosh(z);
  164.         else if (oper == "asinh")
  165.             z = asinh(z);
  166.         else if (oper == "log")
  167.             z = log(z);
  168.         else if (oper == "sqrt")
  169.             z = sqrt(z);
  170.            
  171.     right = fToString(z);
  172.     LST.push_front(right);
  173.     }
  174.    
  175.     float getValue(string &vl)
  176.     {
  177.         // Объявление констант в программе и создание аргумента икс,
  178.         // который используется в качестве основной переменной в подаваемых функциях
  179.         // cout << "\'" << vl << "\'" << endl;
  180.         if (vl == "e")
  181.             return 2.72;
  182.         if (vl == "pi")
  183.             return 3.14;
  184.         if (vl == "x")
  185.             return this->param;
  186.         else
  187.             return stof(vl);
  188.        
  189.     }
  190.    
  191.     string fToString(float &z)
  192.     {
  193.         // Суть: перевод float в stringstream
  194.         stringstream ss;
  195.         string s;
  196.         ss << z; ss >> s;
  197.         return s;
  198.     }
  199.    
  200. public:
  201.     exprPolish(string &line) : exprFilter(line){
  202.         // Конструктор для работы с ОПН
  203.         this->param = 1;
  204.         stack <string> tSTACK;
  205.         list <string> result;
  206.        
  207.        
  208.         while (!this->express.empty())
  209.         {
  210.             // обрабатываем старый express, занося результат в list<>result
  211.             line = this->express.front();
  212.             // Помещение элемента в стек в случае корректности выражения != ")"
  213.             if (tSTACK.empty())
  214.             {
  215.                 if (priority(line) == -2)
  216.                     tSTACK.push(line);
  217.                 else if (priority(line) == -1)
  218.                     result.push_back(line);
  219.                 else if (line != ")") // т.е число
  220.                 {
  221.                  tSTACK.push(line);
  222.                 }
  223.                 else
  224.                     cout << "Incorrect input" << endl;
  225.             }
  226.             else
  227.             {
  228.                 if (priority(line) == -2)
  229.                     tSTACK.push(line);
  230.                 else if (priority(line) == -1)
  231.                 {
  232.                     result.push_back(line);
  233.                 }
  234.                 else if (line == "(")
  235.                 {
  236.                     tSTACK.push(line);
  237.                 }
  238.                 else if (line == ")")
  239.                 {
  240.                     while(tSTACK.top() != "(")
  241.                     {
  242.                         result.push_back(tSTACK.top());
  243.                         tSTACK.pop();
  244.                     }
  245.                     tSTACK.pop();
  246.                     if (!tSTACK.empty() && isTrig(tSTACK.top()))
  247.                     {
  248.                         result.push_back(tSTACK.top());
  249.                         tSTACK.pop();
  250.                     }
  251.                 }
  252.                 else
  253.                 {
  254.                     while(!tSTACK.empty() && (priority(line) <= priority(tSTACK.top())))
  255.                     {
  256.                         result.push_back(tSTACK.top());
  257.                         tSTACK.pop();
  258.                     }
  259.                     tSTACK.push(line);
  260.                 }
  261.             }
  262.             this->express.pop_front();
  263.         }
  264.         // опустошаем остатки стека
  265.         while (!tSTACK.empty())
  266.         {
  267.             result.push_back( tSTACK.top() );
  268.             tSTACK.pop();
  269.         }
  270.        
  271.         // переносим result в express
  272.         this->express = result;
  273.         this->show();
  274.     }
  275.     // вывод стека посредством pop();
  276.     void show (stack<string> st){
  277.         cout << '\t';
  278.         while (!st.empty())
  279.         {
  280.             cout << st.top() << ' ';
  281.             st.pop();
  282.         }
  283.         cout << "<|";
  284.     }
  285.     // вывод списка посредством использования итератора
  286.     void show (){
  287.         list <string>::iterator it = this->express.begin();
  288.        
  289.         for (it; it != this->express.end(); it++)
  290.         cout << *it << ' ';
  291.         cout << endl;
  292.     }
  293. };
  294. class Expression : public exprPolish{
  295.     // Класс обработки выражения
  296. private:
  297.     float RESULT;
  298. public:
  299.     Expression(string &line) : exprPolish(line)
  300.     {
  301.         // Результат присваиваем функции одной переменной
  302.         this->RESULT = this->getResult(1);
  303.         cout << this->RESULT << endl;
  304.         this->param = 0;
  305.     }
  306.  
  307.     float getResult(float arg){
  308.         this->param = arg;
  309.         list <string> XP = this->express;
  310.         // Суть: прокрутка ленты до тех пор,
  311.         // пока не встретим тройку "число число операция"
  312.         // затем совершим необходимые действия
  313.         // и поместим результат в front() списка
  314.         while (XP.size() != 1)
  315.         {
  316.             // this->show(XP);
  317.             string oper = "";
  318.             // смотрим, приняли ли мы операцию
  319.             switch(priority(XP.back()))
  320.             {
  321.                 case -1:
  322.                 // Если подается число, то добавляем в начало списка
  323.                     XP.push_front(XP.back());
  324.                     XP.pop_back();
  325.                     continue;
  326.                 default:
  327.                 // Если другой приоритет операций, то добавляем в конец списка
  328.                     oper = XP.back();
  329.                     XP.pop_back();
  330.                     break;
  331.             }
  332.            
  333.             string right = "";
  334.             // берём правый операнд
  335.             // смотрим, является ли он числом,
  336.             // т.е. priority = -1
  337.             if (priority(XP.back()) != -1)
  338.             {
  339.                 XP.push_front(oper);
  340.                 continue;
  341.             }
  342.             else
  343.             {
  344.                 right = XP.back();
  345.                 XP.pop_back();
  346.             }
  347.             if ((isTrig(oper) == true) && (priority(right) == -1))
  348.             {
  349.                 getTrigResult(oper, right, XP);
  350.                 continue;
  351.             }
  352.             // берём левый операнд, то же самое.
  353.             // в случае неудачи возвращаем в очередь
  354.             // считанные элементы
  355.            
  356.             if (priority(XP.back()) != -1)
  357.             {
  358.                 XP.push_front(oper);
  359.                 XP.push_front(right);
  360.                 continue;
  361.             }
  362.             else // другой приоритет операций
  363.             {
  364.                 string left = XP.back();
  365.                 XP.pop_back();
  366.             // cout << "\t[" << left + ' ' + oper + ' ' + right << "]" << endl;
  367.                 float z; // для результата операции
  368.                 switch(oper[0])
  369.                 {
  370.                     // Бросаем результат в начало списка
  371.                     case '+':
  372.                         z = getValue(left) + getValue(right);
  373.                         XP.push_front(fToString(z));
  374.                         break;
  375.                     case '-':
  376.                         z = getValue(left) - getValue(right);
  377.                         XP.push_front(fToString(z));
  378.                         break;
  379.                     case '*':
  380.                         z = getValue(left) * getValue(right);
  381.                         XP.push_front(fToString(z));
  382.                         break;
  383.                     case '/':
  384.                         z = getValue(left) / getValue(right);
  385.                         XP.push_front(fToString(z));
  386.                         break;
  387.                     case '^':
  388.                         z = power(getValue(left), getValue(right));
  389.                         XP.push_front(fToString(z));
  390.                     default:
  391.                         break;
  392.                 }
  393.             }
  394.         }
  395.        
  396.         return getValue(XP.front());
  397.     }
  398.     void show (){
  399.         // Вывод стека посредством использования итератора
  400.         list <string>::iterator it = this->express.begin();
  401.        
  402.         for (it; it != this->express.end(); it++)
  403.         {
  404.             cout << *it << ' ';
  405.         } cout << " = " << this->RESULT << endl;
  406.     }
  407.     void show (list <string> &lst){
  408.         // Вывод списка посредством использования итератора
  409.         list <string>::iterator it = lst.begin();
  410.        
  411.         for (it; it != lst.end(); it++)
  412.         {
  413.             cout << *it << ' ';
  414.         }
  415.         cout << endl;
  416.     }
  417. };
  418. class Integrate{
  419.     // Класс для работы с методами численного интегрирования
  420. private:
  421.     string sMode;
  422.     Expression * fexpr;
  423.     unsigned int n;
  424.    
  425.     float Trapecium(float a, float b)
  426.     {
  427.         // Метод трапеций
  428.         float Result = 0;
  429.    
  430.         float step = (b - a) / n;
  431.    
  432.         for (float x = a; x < b; x += step)
  433.         {
  434.             Result += fexpr->getResult(x);
  435.         }
  436.         return step * Result;
  437.     }
  438.     float Simpson(float a, float b)
  439.     {
  440.         // Метод Симпсона
  441.         float Result = 0;
  442.    
  443.         float step = (b - a) / (2 * n);
  444.         int z = 0;
  445.         for (float x = a + step; x < b; x += step)
  446.         {
  447.             Result += fexpr->getResult(x) * (z % 2 == 0 ? 4 : 2);
  448.             z++; // 15 / 200 => 16.0852
  449.         }
  450.         // + fa fb => 16.1455
  451.         return (step / 3 * (fexpr->getResult(a) + fexpr->getResult(b) + Result));
  452.     }
  453.    
  454.     float Rectangle(float &a, float &b)
  455.     {
  456.         // Метод центральных прямоугольников
  457.         float Result = 0;
  458.        
  459.         float step = (b - a) / n;
  460.        
  461.         for (float x = a; x < b; x += step)
  462.         {
  463.             Result += fexpr->getResult(x - step/2);
  464.         }
  465.         return step * Result;
  466.     }
  467.    
  468.     // float Gauss(float &a, float &b)
  469.     // {
  470.     //  // Метод Гаусса
  471.     //  float Result = 0;
  472.        
  473.     //  float step = (b - a) / n;
  474.        
  475.     //  for (float x = a: x < b: x += step)
  476.     //  {
  477.     //      Return += fexpr->getResult(x)
  478.     //  }
  479.     // }
  480. public:
  481.     Integrate(string &line, float &a, float &b)
  482.     {
  483.         // Суть: Вычисление интегралов по заданным методам и вывод результатов
  484.         this->sMode = line;
  485.         this->fexpr = new Expression(line);
  486.         this->n = 100;
  487.         cout.precision(7);
  488.        
  489.         cout << "Integral of " << this->sMode;
  490.         cout << " from " << a << " to " << b << ":" << endl;
  491.        
  492.         this->RESULT = this->Trapecium (a, b);
  493.         cout << "Trapecium Method: " << this->RESULT << ';' << endl;
  494.         this->RESULT = this->Simpson (a, b);
  495.         cout << "Simpson's Method: " << this->RESULT << ';' << endl;
  496.         this->RESULT = this->Rectangle (a, b);
  497.         cout << "Rectangle Method: " << this->RESULT << ';' << endl;
  498.     }
  499.     void show()
  500.     {
  501.         this->fexpr->show();
  502.     }
  503.     float RESULT;
  504. };
  505. /*
  506. * пример ввода алгебраического выражения
  507. */
  508. int main ()
  509. {
  510.     fstream input;
  511.     input.open("input_newer.txt", fstream::in);
  512.     vector <Integrate> vect;
  513.     string line = ""; // Считывание без пробелов выражения
  514.    
  515.     float a = 2;
  516.     float b = 3;
  517.     while(getline(input, line, '|'))
  518.     {
  519.         // Пока считываем строку, выводим результат интегрирования, список
  520.         Integrate expr(line, a, b);
  521.         vect.push_back(expr);
  522.         cout << "+++++++++++++++++++++++++++" << endl;
  523.     }
  524. return 0;
  525. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement