Advertisement
Guest User

Untitled

a guest
Jun 19th, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.63 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement