SHARE
TWEET

Untitled

a guest Jun 19th, 2019 55 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <math.h>
  3. #include <string>
  4. #include <map>
  5. #include <chrono>
  6.  
  7. using namespace std;
  8. map < string, double > vars;
  9. void rungekutta(double, double, double, double, string &);
  10. void progncor(double, double, double, double, string &, double);
  11. double calc(string & , double, double);
  12. double expr(string &, unsigned &, double, double);
  13. double term(string &, unsigned &, double, double);
  14. double factor(string &, unsigned &, double, double);
  15. double base(string &, unsigned &, double, double);
  16. double number(string &, unsigned &);
  17. double identif(string &, unsigned &, double, double);
  18. double function(string &, string &, unsigned &, double, double);
  19. int main()
  20. {
  21.     setlocale(LC_ALL, "Rus");
  22.     int x;
  23.     string expr;
  24.     bool pro = true;
  25.     double a, b, h, y0, eps;
  26.     do {
  27.         do {
  28.             cout << endl << "Выберите метод решения: " << endl;
  29.             cout << "1. Метод Рунге-Кутты 4-го порядка;" << endl;
  30.             cout << "2. Метод прогноза и коррекции;" << endl;
  31.             cout << "3. Выйти." << endl;
  32.  
  33.             cout << "\nВведите номер операции: ";
  34.             cin >> x;
  35.             if (!cin) {
  36.                 pro = false;
  37.                 system("cls");
  38.                 cin.clear();
  39.                 while (cin.get() != '\n');
  40.                 cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl;
  41.             }
  42.             switch (x) {
  43.             case 3:
  44.                 exit(-1);
  45.                 break;
  46.             case 1:
  47.                 system("cls");
  48.                 cout << "Задайте интервал [a; b]: " << endl << "a = "; cin >> a; if (!cin) {
  49.                     pro = false;
  50.                     system("cls");
  51.                     cin.clear();
  52.                     while (cin.get() != '\n');
  53.                     cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
  54.                 } cout << "b = "; cin >> b; if (!cin) {
  55.                     pro = false;
  56.                     system("cls");
  57.                     cin.clear();
  58.                     while (cin.get() != '\n');
  59.                     cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
  60.                 }
  61.                 cout << "Задайте шаг h: " << endl << "h = "; cin >> h; if (!cin) {
  62.                     pro = false;
  63.                     system("cls");
  64.                     cin.clear();
  65.                     while (cin.get() != '\n');
  66.                     cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
  67.                 }
  68.                 cout << "Задайте начальные условия (Y( " << a << " ) = Y0): " << endl; cout << "Y0 = "; cin >> y0; if (!cin) {
  69.                     pro = false;
  70.                     system("cls");
  71.                     cin.clear();
  72.                     while (cin.get() != '\n');
  73.                     cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
  74.                 }
  75.                 cout << "Введите выражение:" << "y' = ";
  76.                 cin >> expr;
  77.                
  78.                 rungekutta(a, b, h, y0, expr);
  79.                
  80.                
  81.                 break;
  82.             case 2:
  83.                 system("cls");
  84.                 cout << "Задайте интервал [a; b]: " << endl << "a = "; cin >> a; if (!cin) {
  85.                     pro = false;
  86.                     system("cls");
  87.                     cin.clear();
  88.                     while (cin.get() != '\n');
  89.                     cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
  90.                 } cout << "b = "; cin >> b; if (!cin) {
  91.                     pro = false;
  92.                     system("cls");
  93.                     cin.clear();
  94.                     while (cin.get() != '\n');
  95.                     cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
  96.                 }
  97.                 cout << "Задайте шаг h: " << endl << "h = "; cin >> h; if (!cin) {
  98.                     pro = false;
  99.                     system("cls");
  100.                     cin.clear();
  101.                     while (cin.get() != '\n');
  102.                     cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
  103.                 }
  104.                 cout << "Задайте начальные условия (Y( " << a << " ) = Y0): " << endl; cout << "Y0 = "; cin >> y0; if (!cin) {
  105.                     pro = false;
  106.                     system("cls");
  107.                     cin.clear();
  108.                     while (cin.get() != '\n');
  109.                     cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
  110.                 }
  111.                 cout << "Введите нужную точность вычислений: " << endl << "є = "; cin >> eps; if (!cin) {
  112.                     pro = false;
  113.                     system("cls");
  114.                     cin.clear();
  115.                     while (cin.get() != '\n');
  116.                     cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
  117.                 }
  118.                 cout << "Введите выражение:" << "y' = ";
  119.                 cin >> expr;
  120.                
  121.                 progncor(a, b, y0, h, expr, eps);
  122.                
  123.                 break;
  124.            
  125.             default:
  126.                 system("cls");
  127.                 cout << "Неверный ввод. Попробуйте еще раз." << endl;
  128.                 break;
  129.             }
  130.         } while (x != 3);
  131.     } while (pro != true);
  132. }void rungekutta(double a, double b, double h, double y0, string &expr) {
  133.     auto begin = chrono::steady_clock::now();
  134.     double n = (b - a) / h;
  135.     double K1, K2, K3, K4;
  136.     double y = y0;
  137.     double x0 = a;
  138.     for (int i = 0; i <= n; i++) {
  139.         double X = x0 + 0.5*h;
  140.         double X4 = x0 + h;
  141.         K1 = calc(expr, x0, y);
  142.         double Y2 = y + 0.5 * h * K1;
  143.         K2 = calc(expr, X, Y2);
  144.         double Y3 = y + 0.5 * h * K2;
  145.         K3 = calc(expr, X, Y3);
  146.         double Y4 = y + h * K3;
  147.         K4 = calc(expr, X4, Y4);
  148.         cout << "Y(" << i << ") = " << y << "  x0 = " << x0 << "  y = "<<  y << "  K1 = "  << K1 << "  K2 = " << K2 << "  K3 = " << K3 << "  K4 = " << K4 << endl;
  149.         y = y + (h / 6.0)*(K1 + 2 * K2 + 2 * K3 + K4);
  150.         x0 += h;
  151.     }
  152.     auto end = chrono::steady_clock::now();
  153.     auto elapsed_ns = chrono::duration_cast <chrono::nanoseconds>(end - begin);
  154.     cout << "\n" << "Метод Рунге-Кутты 4-го порядка. Время работы - " << elapsed_ns.count() << "нс." << endl;
  155. }
  156.  
  157. void progncor(double a, double b, double y0, double h, string &str, double eps) {
  158.     auto begin1 = chrono::steady_clock::now();
  159.     double n = (b - a) / h;
  160.     double K1, K2, K3, K4;
  161.     double *x = new double[n+1];
  162.     double *y = new double[n+1];
  163.     double *Ypr = new double[n + 1];
  164.     double *Ykr = new double[n + 1];;
  165.     x[0] = a;
  166.     y[0] = y0;
  167.     for ( int i = 0; i <= 3; i++)
  168.     {
  169.         K1 = h * calc(str, x[i], y[i]);
  170.         K2 = h * calc(str, x[i] + h / 2, y[i] + K1 / 2);
  171.         K3 = h * calc(str, x[i] + h / 2, y[i] + K2 / 2);
  172.         K4 = h * calc(str, x[i] + h, y[i] + K3);
  173.         y[i + 1] = y[i] + (1.0/6.0)*(K1 + 2 * K2 + 2 * K3 + K4);
  174.         x[i + 1] = x[i] + h;
  175.     }
  176.     for (int i = 4; x[i] <= (b+h); i++) {
  177.         Ypr[i] = y[i - 4] + ((4.0*h) / 3.0)*(2 * calc(str, x[i - 3], y[i - 3]) - calc(str, x[i - 2], y[i - 2]) + 2 * calc(str, x[i - 1], y[i - 1]));
  178.  
  179.         Ykr[i] = y[i - 2] + (h / 3.0)*(calc(str, x[i - 2], y[i - 2]) + 4 * calc(str, x[i - 1], y[i - 1]) + calc(str, x[i], Ypr[i]));
  180.  
  181.         double abs_p = abs(Ykr[i] - Ypr[i]) / 29.0;
  182.  
  183.         if (abs_p > eps) {
  184.             y[i] = Ykr[i];
  185.         }
  186.         else {
  187.             y[i] = Ypr[i];
  188.         }
  189.         x[i + 1] = x[i] + h;
  190.     }
  191.     for (int i = 0; i < n + 1; i++) {
  192.         cout << "Овтеты: " << endl << "X(" << i << ") = " << x[i] << "   Y(" << i << ")  = " << y[i] << endl;
  193.     }
  194.     for (int i = 4; i < n + 1; i++) {
  195.         cout << "   Y(" << i << ")прогн. = " << Ypr[i] << "   Y(" << i << ")корр. = " << Ykr[i] << endl;
  196.     }
  197.     auto end1 = chrono::steady_clock::now();
  198.     auto elapsed_ns1 = chrono::duration_cast <chrono::nanoseconds>(end1 - begin1);
  199.     cout << "\n" << "Метод прогноз и коррекции(метод Милна). Время работы - " << elapsed_ns1.count() << "нс." << endl;
  200. }
  201. double calc(string &str, double x, double y) {
  202.     unsigned int index = 0;
  203.     double res = 0.0;
  204.     res = expr(str, index, x , y);
  205.     if (index < str.length() - 1) {
  206.         cout << "Неверный ввод! " << index + 1 << endl;
  207.         exit(-1);
  208.     }
  209.     return res;
  210. }
  211. double expr(string &str, unsigned &index, double x, double y) {
  212.     double res;
  213.     char oper;
  214.     res = term(str, index, x, y);
  215.     while (index < str.length() && str[index] == '+' || str[index] == '-') {
  216.         oper = str[index];
  217.         ++index;
  218.         switch (oper) {
  219.         case '+':
  220.             res += term(str, index, x, y);
  221.             break;
  222.         case '-':
  223.             res -= term(str, index, x, y);
  224.             break;
  225.  
  226.         }
  227.     }
  228.     return res;
  229. }
  230. double term(string &str, unsigned &index, double x, double y) {
  231.     double res;
  232.     char oper;
  233.     double div;
  234.     res = factor(str, index, x, y);
  235.     while (index < str.length() && str[index] == '*' || str[index] == '/') {
  236.         oper = str[index];
  237.         ++index;
  238.         switch (oper) {
  239.         case '*':
  240.             res *= factor(str, index, x, y);
  241.             break;
  242.         case '/':
  243.             div = factor(str, index, x, y);
  244.             if (div == 0.0) {
  245.                 cout << "Деление на ноль!" << endl;
  246.                 system("PAUSE");
  247.  
  248.                 exit(-1);
  249.             }
  250.             res /= div;
  251.             break;
  252.         }
  253.     }
  254.     return res;
  255. }
  256. double factor(string &str, unsigned &index, double x, double y) {
  257.     double res;
  258.     if (index >= str.length()) {
  259.         cout << "Неожиданный конец строки!" << endl;
  260.         system("PAUSE");
  261.         exit(-1);
  262.     }
  263.     switch (str[index]) {
  264.     case '+':
  265.         ++index;
  266.         res = factor(str, index, x, y);
  267.         break;
  268.     case '-':
  269.         ++index;
  270.         res = -factor(str, index, x, y);
  271.         break;
  272.     default:
  273.         res = base(str, index, x, y);
  274.         if (index <= str.length() - 1 && str[index] == '^') {
  275.             ++index;
  276.             res = pow(res, factor(str, index, x, y));
  277.         }
  278.     }
  279.     return res;
  280. }
  281. double base(string &str, unsigned &index, double x, double y) {
  282.     double res;
  283.     if (index >= str.length()) {
  284.         cout << "Неожиданный конец строки!" << endl;
  285.         system("PAUSE");
  286.         exit(-1);
  287.     }
  288.     if (str[index] == '(') {
  289.         ++index;
  290.         res = expr(str, index, x, y);
  291.         if (index >= str.length() || str[index] != ')') {
  292.             cout << "Ожидается ')' в позиции " << index + 2 << endl;
  293.             system("PAUSE");
  294.             exit(-1);
  295.         }
  296.         ++index;
  297.     }
  298.     else {
  299.         if (str[index] >= '0' && str[index] <= '9') {
  300.             res = number(str, index);
  301.         }
  302.         else {
  303.             if ((str[index] >= 'A' && str[index] <= 'Z') || (str[index] >= 'a' && str[index] <= 'z') || (str[index] == '_')) {
  304.                 res = identif(str, index, x, y);
  305.             }
  306.             else {
  307.                 cout << "Некорректный символ в позиции" << index + 1 << endl;
  308.                 system("PAUSE");
  309.                 exit(-1);
  310.             }
  311.         }
  312.     }
  313.     return res;
  314. }
  315. double number(string &str, unsigned &index){
  316.     double res = 0.0;
  317.     char digit;
  318.     double k = 10.0;
  319.     while (index < str.length()) {
  320.         digit = str[index++];
  321.         if (digit >= '0' && digit <= '9') {
  322.             res = res * 10.0 + (digit - '0');
  323.         }
  324.         else {
  325.             --index;
  326.             break;
  327.         }
  328.     }
  329.     if (index < str.length()) {
  330.         digit = str[index++];
  331.     }
  332.     if (digit == '.' || digit == ',') {
  333.         while (index < str.length()) {
  334.             digit = str[index++];
  335.             if (digit >= '0' && digit <= '9') {
  336.                 res += (digit - '0') / k;
  337.                 k *= 10;
  338.             }
  339.             else {
  340.                 --index;
  341.                 break;
  342.             }
  343.         }
  344.     }
  345.     else {
  346.         --index;
  347.     }
  348.     return res;
  349. }
  350. double identif(string &str, unsigned &index, double x, double y) {
  351.     string name = "";
  352.     double res;
  353.     while (index < str.length() && (str[index] >= 'a' && str[index] <= 'z') ||
  354.         (str[index] >= 'A' && str[index] <= 'Z') ||
  355.         (str[index] >= '0' && str[index] <= '9') ||
  356.         (str[index] == '_')) {
  357.         name += str[index++];
  358.     }
  359.     if (index < str.length() && str[index] == '(') {
  360.         ++index;
  361.         res = function(name, str, index, x, y);
  362.         if (index >= str.length() && str[index] != ')') {
  363.             cout << "Ожидается ')' в позиции " << index + 2 << endl;
  364.             system("PAUSE");
  365.             exit(-1);
  366.         }
  367.         ++index;
  368.     }
  369.     else {
  370.         if (strcmp(name.c_str(), "x") == 0) {
  371.             vars.insert(pair<const string, double >(name, x));
  372.         }
  373.         else {
  374.             if (strcmp(name.c_str(), "y") == 0) {
  375.                 vars.insert(pair<const string, double >(name, y));
  376.             }
  377.             else {
  378.                 cout << "Введена неверная переменная! " << name;
  379.                 system("PAUSE");
  380.                 exit(-1);
  381.             }
  382.         }
  383.         res = vars[name];  
  384.         vars.clear();
  385.     }
  386.     return res;
  387. }
  388. double function(string &name, string &str, unsigned &index, double x, double y)
  389. {
  390.     double argument = expr(str, index, x, y);
  391.  
  392.     if (strcmp(name.c_str(), "acos") == 0) {
  393.         return acos(argument);
  394.     }
  395.  
  396.     if (strcmp(name.c_str(), "asin") == 0) {
  397.         return asin(argument);
  398.     }
  399.  
  400.     if (strcmp(name.c_str(), "atan") == 0) {
  401.         return atan(argument);
  402.     }
  403.  
  404.     if (strcmp(name.c_str(), "cos") == 0) {
  405.         return cos(argument);
  406.     }
  407.  
  408.     if (strcmp(name.c_str(), "cosh") == 0) {
  409.         return cosh(argument);
  410.     }
  411.  
  412.     if (strcmp(name.c_str(), "exp") == 0) {
  413.         return exp(argument);
  414.     }
  415.  
  416.     if (strcmp(name.c_str(), "log") == 0) {
  417.         return log(argument);
  418.     }
  419.  
  420.     if (strcmp(name.c_str(), "log10") == 0) {
  421.         return log10(argument);
  422.     }
  423.  
  424.     if (strcmp(name.c_str(), "sin") == 0) {
  425.     return sin(argument);
  426. }
  427.  
  428.     if (strcmp(name.c_str(), "sinh") == 0) {
  429.         return sinh(argument);
  430.     }
  431.  
  432.  
  433.     if (strcmp(name.c_str(), "sqrt") == 0) {
  434.         return sqrt(argument);
  435.     }
  436.  
  437.     if (strcmp(name.c_str(), "tan") == 0) {
  438.         return tan(argument);
  439.     }
  440.  
  441.     if (strcmp(name.c_str(), "tanh") == 0) {
  442.         return tanh(argument);
  443.     }
  444.  
  445.     cout << "Неизвестная функция!" << endl;
  446.     system("PAUSE");
  447.     exit(-1);
  448. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top