Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <list>
- #include <stack>
- #include <sstream>
- #include <vector>
- #include <cmath>
- using namespace std;
- class exprFilter{ // Базовый класс для работы с выражениями
- protected:
- list <string> express; // Список для выражения
- private:
- void show(){ // Вывод списка выражений
- list<string>::iterator it = this->express.begin(); // Введем итератор it как начало списка
- for (it; it != this->express.end(); it++) // Выводим список
- {
- cout << *it << ' ';
- }
- cout << endl;
- }
- // взятие приоритета операции
- // вернёт -1, если char не является операцией
- int priority(char &c){
- // символ & используется для того, чтобы создать копию объекта
- switch (c)
- {
- case '(':
- case ')':
- return 0;
- case '+': case '-':
- return 1;
- case '*': case '/':
- return 2;
- case '^':
- return 3;
- default:
- return -1;
- }
- }
- public:
- exprFilter(string &line){
- // Фильтр выражений, используемый для того, чтобы правильно обрабатывать данные,
- // подаваемые в исходной строке
- cout << line << endl;
- stringstream in;
- in << line;
- // Посимвольная фильтрация потока (строки)
- char c = ' '; line = "";
- while (in >> c)
- {
- if (priority(c) != -1) // Т.е. принята операция или скобка
- {
- // Если в буфере уже что-либо записано
- if (line != "")
- {
- // то выбрасываем записанный элемент из буфера в очередь
- this->express.push_back(line);
- // и обнуляем
- line = "";
- }
- // переводим переменную c в string и бросаем в очередь
- line += c;
- this->express.push_back(line);
- // снова обнуляем
- line = "";
- }
- else // Если принят операнд
- {
- line += c;
- }
- }
- if (line != "") // Если же string не пуст
- this->express.push_back(line); // Добавляем в конец списка элемент
- this->show(); // Выводит результат работы конструктора
- }
- };
- class exprPolish : public exprFilter{
- // Класс для работы с переводом выражения из инфиксной формы записи в ОПН
- protected:
- float param; // Параметр
- bool isTrig(string &oper)
- {
- // Функция, предназначенная для восприятия математических выражений в программе
- return (oper == "sin" || oper == "cos" || oper == "tan" || oper == "asin"
- || oper == "acos" || oper == "atan" || oper == "sinh" || oper == "log"
- || oper == "cosh" || oper == "tanh" || oper == "atanh" || oper == "sqrt");
- }
- // Взятие приоритета операции
- // вернёт -1, если string не является операцией
- int priority(string &s)
- {
- if (isTrig(s)) // Если математические выражения
- return -2;
- if (s.length() > 1) //?
- return -1;
- switch (s[0]) //?
- {
- case '(':
- case ')':
- return 0;
- case '+': case '-':
- return 1;
- case '*': case '/':
- return 2;
- case '^':
- return 3;
- default:
- return -1;
- }
- }
- /*
- * подаются копии, т.к. в Expression::getResult()
- * используются аргументы от stof(string);
- */
- float power(float z, float c)
- {
- // Функция возведения в степень и различные ситуации
- if (c == 0)
- return 1;
- if (c == 1)
- return z;
- float result;
- if (c < 0)
- {
- c = abs(c);
- z = 1/z;
- }
- result = z;
- for (unsigned int k = 1; k < c; k++) //?
- {
- result *= z;
- }
- return result;
- }
- void getTrigResult(string &oper, string &right, list<string> &LST)
- {
- // Суть: в данном методе просматривается выражение, и если окажется,
- // что выражение - тригонометрическая функция от параметра икс,
- // то правильно ее обработает и поместит в начало списка LST
- float z = getValue(right); // где z - тригонометрическая функция от икс
- if (oper == "sin")
- z = sin(z);
- else if (oper == "cos")
- z = cos(z);
- else if (oper == "tan")
- z = tan(z);
- else if (oper == "atan")
- z = atan(z);
- else if (oper == "asin")
- z = asin(z);
- else if (oper == "acos")
- z = acos(z);
- else if (oper == "cosh")
- z = cosh(z);
- else if (oper == "sinh")
- z = sinh(z);
- else if (oper == "acosh")
- z = acosh(z);
- else if (oper == "asinh")
- z = asinh(z);
- else if (oper == "log")
- z = log(z);
- else if (oper == "sqrt")
- z = sqrt(z);
- right = fToString(z);
- LST.push_front(right);
- }
- float getValue(string &vl)
- {
- // Объявление констант в программе и создание аргумента икс,
- // который используется в качестве основной переменной в подаваемых функциях
- // cout << "\'" << vl << "\'" << endl;
- if (vl == "e")
- return 2.72;
- if (vl == "pi")
- return 3.14;
- if (vl == "x")
- return this->param;
- else
- return stof(vl);
- }
- string fToString(float &z)
- {
- // Суть: перевод float в stringstream
- stringstream ss;
- string s;
- ss << z; ss >> s;
- return s;
- }
- public:
- exprPolish(string &line) : exprFilter(line){
- // Конструктор для работы с ОПН
- this->param = 1;
- stack <string> tSTACK;
- list <string> result;
- while (!this->express.empty())
- {
- // обрабатываем старый express, занося результат в list<>result
- line = this->express.front();
- // Помещение элемента в стек в случае корректности выражения != ")"
- if (tSTACK.empty())
- {
- if (priority(line) == -2)
- tSTACK.push(line);
- else if (priority(line) == -1)
- result.push_back(line);
- else if (line != ")") // т.е число
- {
- tSTACK.push(line);
- }
- else
- cout << "Incorrect input" << endl;
- }
- else
- {
- if (priority(line) == -2)
- tSTACK.push(line);
- else if (priority(line) == -1)
- {
- result.push_back(line);
- }
- else if (line == "(")
- {
- tSTACK.push(line);
- }
- else if (line == ")")
- {
- while(tSTACK.top() != "(")
- {
- result.push_back(tSTACK.top());
- tSTACK.pop();
- }
- tSTACK.pop();
- if (!tSTACK.empty() && isTrig(tSTACK.top()))
- {
- result.push_back(tSTACK.top());
- tSTACK.pop();
- }
- }
- else
- {
- while(!tSTACK.empty() && (priority(line) <= priority(tSTACK.top())))
- {
- result.push_back(tSTACK.top());
- tSTACK.pop();
- }
- tSTACK.push(line);
- }
- }
- this->express.pop_front();
- }
- // опустошаем остатки стека
- while (!tSTACK.empty())
- {
- result.push_back( tSTACK.top() );
- tSTACK.pop();
- }
- // переносим result в express
- this->express = result;
- this->show();
- }
- // вывод стека посредством pop();
- void show (stack<string> st){
- cout << '\t';
- while (!st.empty())
- {
- cout << st.top() << ' ';
- st.pop();
- }
- cout << "<|";
- }
- // вывод списка посредством использования итератора
- void show (){
- list <string>::iterator it = this->express.begin();
- for (it; it != this->express.end(); it++)
- cout << *it << ' ';
- cout << endl;
- }
- };
- class Expression : public exprPolish{
- // Класс обработки выражения
- private:
- float RESULT;
- public:
- Expression(string &line) : exprPolish(line)
- {
- // Результат присваиваем функции одной переменной
- this->RESULT = this->getResult(1);
- cout << this->RESULT << endl;
- this->param = 0;
- }
- float getResult(float arg){
- this->param = arg;
- list <string> XP = this->express;
- // Суть: прокрутка ленты до тех пор,
- // пока не встретим тройку "число число операция"
- // затем совершим необходимые действия
- // и поместим результат в front() списка
- while (XP.size() != 1)
- {
- // this->show(XP);
- string oper = "";
- // смотрим, приняли ли мы операцию
- switch(priority(XP.back()))
- {
- case -1:
- // Если подается число, то добавляем в начало списка
- XP.push_front(XP.back());
- XP.pop_back();
- continue;
- default:
- // Если другой приоритет операций, то добавляем в конец списка
- oper = XP.back();
- XP.pop_back();
- break;
- }
- string right = "";
- // берём правый операнд
- // смотрим, является ли он числом,
- // т.е. priority = -1
- if (priority(XP.back()) != -1)
- {
- XP.push_front(oper);
- continue;
- }
- else
- {
- right = XP.back();
- XP.pop_back();
- }
- if ((isTrig(oper) == true) && (priority(right) == -1))
- {
- getTrigResult(oper, right, XP);
- continue;
- }
- // берём левый операнд, то же самое.
- // в случае неудачи возвращаем в очередь
- // считанные элементы
- if (priority(XP.back()) != -1)
- {
- XP.push_front(oper);
- XP.push_front(right);
- continue;
- }
- else // другой приоритет операций
- {
- string left = XP.back();
- XP.pop_back();
- // cout << "\t[" << left + ' ' + oper + ' ' + right << "]" << endl;
- float z; // для результата операции
- switch(oper[0])
- {
- // Бросаем результат в начало списка
- case '+':
- z = getValue(left) + getValue(right);
- XP.push_front(fToString(z));
- break;
- case '-':
- z = getValue(left) - getValue(right);
- XP.push_front(fToString(z));
- break;
- case '*':
- z = getValue(left) * getValue(right);
- XP.push_front(fToString(z));
- break;
- case '/':
- z = getValue(left) / getValue(right);
- XP.push_front(fToString(z));
- break;
- case '^':
- z = power(getValue(left), getValue(right));
- XP.push_front(fToString(z));
- default:
- break;
- }
- }
- }
- return getValue(XP.front());
- }
- void show (){
- // Вывод стека посредством использования итератора
- list <string>::iterator it = this->express.begin();
- for (it; it != this->express.end(); it++)
- {
- cout << *it << ' ';
- } cout << " = " << this->RESULT << endl;
- }
- void show (list <string> &lst){
- // Вывод списка посредством использования итератора
- list <string>::iterator it = lst.begin();
- for (it; it != lst.end(); it++)
- {
- cout << *it << ' ';
- }
- cout << endl;
- }
- };
- class Integrate{
- // Класс для работы с методами численного интегрирования
- private:
- string sMode;
- Expression * fexpr;
- unsigned int n;
- float Trapecium(float a, float b)
- {
- // Метод трапеций
- float Result = 0;
- float step = (b - a) / n;
- for (float x = a; x < b; x += step)
- {
- Result += fexpr->getResult(x);
- }
- return step * Result;
- }
- float Simpson(float a, float b)
- {
- // Метод Симпсона
- float Result = 0;
- float step = (b - a) / (2 * n);
- int z = 0;
- for (float x = a + step; x < b; x += step)
- {
- Result += fexpr->getResult(x) * (z % 2 == 0 ? 4 : 2);
- z++; // 15 / 200 => 16.0852
- }
- // + fa fb => 16.1455
- return (step / 3 * (fexpr->getResult(a) + fexpr->getResult(b) + Result));
- }
- float Rectangle(float &a, float &b)
- {
- // Метод центральных прямоугольников
- float Result = 0;
- float step = (b - a) / n;
- for (float x = a; x < b; x += step)
- {
- Result += fexpr->getResult(x - step/2);
- }
- return step * Result;
- }
- // float Gauss(float &a, float &b)
- // {
- // // Метод Гаусса
- // float Result = 0;
- // float step = (b - a) / n;
- // for (float x = a: x < b: x += step)
- // {
- // Return += fexpr->getResult(x)
- // }
- // }
- public:
- Integrate(string &line, float &a, float &b)
- {
- // Суть: Вычисление интегралов по заданным методам и вывод результатов
- this->sMode = line;
- this->fexpr = new Expression(line);
- this->n = 100;
- cout.precision(7);
- cout << "Integral of " << this->sMode;
- cout << " from " << a << " to " << b << ":" << endl;
- this->RESULT = this->Trapecium (a, b);
- cout << "Trapecium Method: " << this->RESULT << ';' << endl;
- this->RESULT = this->Simpson (a, b);
- cout << "Simpson's Method: " << this->RESULT << ';' << endl;
- this->RESULT = this->Rectangle (a, b);
- cout << "Rectangle Method: " << this->RESULT << ';' << endl;
- }
- void show()
- {
- this->fexpr->show();
- }
- float RESULT;
- };
- /*
- * пример ввода алгебраического выражения
- */
- int main ()
- {
- fstream input;
- input.open("input_newer.txt", fstream::in);
- vector <Integrate> vect;
- string line = ""; // Считывание без пробелов выражения
- float a = 2;
- float b = 3;
- while(getline(input, line, '|'))
- {
- // Пока считываем строку, выводим результат интегрирования, список
- Integrate expr(line, a, b);
- vect.push_back(expr);
- cout << "+++++++++++++++++++++++++++" << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement