Advertisement
n1k1t0s

KrivoeDerevo

May 24th, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.31 KB | None | 0 0
  1. //#include <conio.h>
  2. #include <stdio.h>
  3. #include <iostream>
  4. #include <string.h>
  5. #include <ctime>
  6. #include <stdlib.h>
  7. #include <locale.h>
  8.  
  9. using namespace std;
  10. struct B_tree {
  11. B_tree* left;
  12. B_tree* right;
  13. double value = 0;
  14. char per[100];
  15. };
  16. void print_menu() {
  17. puts("0-выход");
  18. puts("1-произвольное выражение");
  19. puts("2-выражение из варианта (7/(a+3))/(4-(1+3b))");
  20. }
  21. //приоритет операций : приоритет 1 для сложения и вычитания; 2 для умножения и деления
  22. int priority(char c) {
  23. switch (c) {
  24. case '+':
  25. case '-':
  26. return 1;
  27. case '*':
  28. case '/':
  29. return 2;
  30. }
  31. return 100; // это не оперция, пропускаем ее
  32. }
  33. //bool is_space(char c) {
  34. //return (c == ' ') || (c == '\t');
  35. //}
  36.  
  37. //bool is_digit(char c) {
  38. // return ((c >= '0') && (c <= '9') || (c == '.') || (c == ','));
  39. //}
  40.  
  41. bool is_alpha(char c) {
  42. return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
  43. }
  44.  
  45. bool is_bracket(char c) {
  46. return (c == '(' || c == ')');
  47. }
  48.  
  49. bool is_operation(char c) {
  50. return (c == '+' || c == '-' || c == '*' || c == '/');
  51. }
  52.  
  53. //cоздание дерева
  54. B_tree * AddTree(char term[][50], int left, int right)
  55. {
  56. B_tree* MyTree = new B_tree;
  57.  
  58. if (left == right) {
  59. strcpy(MyTree->per, term[left]);
  60. MyTree->left = NULL;
  61. MyTree->right = NULL;
  62. return MyTree;
  63. }
  64. int MinPtr = 100;
  65. int k = 0;
  66. int nest = 0;//счетчик вложенных скобок
  67.  
  68. for (int i = left; i <= right; i++) {
  69. char c = term[i][0];
  70. if (c == '(') {
  71. nest++;
  72. continue;
  73. }
  74. if (c == ')') {
  75. nest--;
  76. continue;
  77. }
  78. if (nest > 0) {
  79. continue;
  80. }
  81. int ptr = priority(c);
  82. if (ptr <= MinPtr) {
  83. MinPtr = ptr;
  84. k = i;
  85. }
  86.  
  87. }
  88. if (MinPtr == 100 && term[left][0] == '('&&term[right][0] == ')') {
  89. return AddTree(term, left + 1, right - 1);
  90. }
  91.  
  92. strcpy(MyTree->per, term[k]);
  93. MyTree->left = AddTree(term, left, k - 1);
  94. MyTree->right = AddTree(term, k + 1, right);
  95.  
  96. return MyTree;
  97. }
  98. //печать дерева
  99. void Print_Tree(B_tree *MyTree, int lev) {
  100. if (MyTree) {
  101. Print_Tree(MyTree->left, lev + 1);
  102. for (int i = 0; i < lev; i++)
  103. cout << "";
  104. cout << MyTree->per << endl;
  105. Print_Tree(MyTree->right, lev + 1);
  106. }
  107. }
  108. //печать прямого обхода
  109. void Print_Premoi_obhod(B_tree * MyTree) {
  110. if (MyTree != NULL) {
  111. cout << MyTree->per;
  112. Print_Premoi_obhod(MyTree->left);
  113. Print_Premoi_obhod(MyTree->right);
  114. }
  115. }
  116. //печать симметричного обхода
  117. void Print_Simmetr_obhod(B_tree *MyTree) //рекурсивная функция печати бинарного дерева
  118. {
  119. if (MyTree != NULL) //пока не встретится пустой узел
  120. {
  121. Print_Simmetr_obhod(MyTree->left); //рекурсивный вызов функции для левого поддерева
  122. cout << MyTree->per; //печать узла дерева
  123. Print_Simmetr_obhod(MyTree->right); // рекурсивный вызов функции для правого поддерева
  124. }
  125. }
  126. //печать обратного обхода
  127. void Print_Obrat_obhod(B_tree *MyTree) {
  128. if (MyTree != NULL) {
  129. Print_Obrat_obhod(MyTree->left);
  130. Print_Obrat_obhod(MyTree->right);
  131. cout << MyTree->per;
  132. }
  133. }
  134. void Print(B_tree *MyTree) {
  135. cout << endl << "Prymoi obhod" << endl<<endl;
  136. Print_Premoi_obhod(MyTree);
  137. cout << endl << "Simmetrichnyi obhod" << endl<<endl;
  138. Print_Simmetr_obhod(MyTree);
  139. cout << endl << "Obratnyi obhod" << endl<<endl;
  140. Print_Obrat_obhod(MyTree);
  141. cout << endl;
  142. }
  143.  
  144. //освобождение памяти выделенное под бинарное дерево
  145. void del_tree(B_tree **MyTree){ // очистка памяти
  146. B_tree *current;
  147. current = *MyTree;
  148. if (*MyTree != NULL) {
  149. del_tree(&(*MyTree)->left);
  150. del_tree(&(*MyTree)->right);
  151. delete *MyTree;
  152. }
  153. }
  154. bool Proverka(char *str) {
  155.  
  156. int left=0,right = 0;
  157. for (int i = 0; i < strlen(str); i++) {
  158. if (str[i] == '(') left++;
  159. if (str[i] == ')') right++;
  160. if (left < right) return false;
  161. if (!isdigit(str[i]) && !is_alpha(str[i]) && !is_operation(str[i]) && !is_bracket(str[i])) {
  162. return false;
  163. }
  164. }
  165. return right == left;
  166.  
  167. }
  168. //унарные операции
  169. void Un_operas (char *str){
  170. char un_plus[] = "0+";
  171. char un_minus[] = "0-";
  172. char simvol[] = "0123456789.";
  173. char *tmp = new char[150];
  174. int k_op = 0;
  175. if (*str == '+') {
  176. strcpy(tmp, str + 1);
  177. *str = '\0';
  178. strcat(str, un_plus);
  179. strcat(str, tmp);
  180. }
  181. if (*str == '-') {
  182. strcpy(tmp, str + 1);
  183. *str = '\0';
  184. strcat(str, un_minus);
  185. strcat(str, tmp);
  186. }
  187. for (int i = 0; i < strlen(str); i++) {
  188. if ((str[i - 1] == '(') ) {
  189. if (str[i] == '-') {
  190. strcpy(tmp, str + i + 1);
  191. *(str + i) = '\0';
  192. strcat(str, un_minus);
  193. strcat(str, tmp);
  194. }
  195. if (str[i] == '+') {
  196. strcpy(tmp, str + i + 1);
  197. *(str + i) = '\0';
  198. strcat(str, un_plus);
  199. strcat(str, tmp);
  200. }
  201. }
  202. }
  203. }
  204. int IsNumber(B_tree* MyTree) {
  205. int i = 0;
  206. if (!MyTree)
  207. return 0;
  208. while (MyTree->per[i])
  209. if (!strchr("0123456789", MyTree->per[i++]))
  210. return 0;
  211. return 1;
  212. }
  213. //вычисление
  214. double Calculate(B_tree * MyTree) {
  215. double a, b, c=0;
  216. // можно ли вычислить
  217. if (!MyTree || !IsNumber(MyTree->left) || !IsNumber(MyTree->right))
  218. return 0;
  219. //получить данные от сыновей
  220. a = Calculate(MyTree->left);
  221. std::cout<<a<<endl;
  222. b = Calculate(MyTree->right);
  223. //выполнить операцию
  224. switch (MyTree->per[0])
  225. {
  226. case'+':
  227. {
  228. c = a + b;
  229. return c;
  230. break;
  231. }
  232. case'-':
  233. {
  234. c = a - b;
  235. return c;
  236. break;
  237. }
  238. case'*':
  239. {
  240. c = a * b;
  241. return c;
  242. break;
  243. }
  244. case'/':
  245. if (MyTree->right->per == "0")
  246. throw ("Деление на 0!");
  247. c = a / b;
  248. return c;
  249. break;
  250. }
  251. //удалить ненужные вершины
  252. delete MyTree->left;
  253. delete MyTree->right;
  254. //обновить вершину
  255. //MyTree = c;
  256. //itoa(c,MyTree->per,10);
  257. MyTree->left = nullptr;
  258. MyTree->right = nullptr;
  259. }
  260. //massivv
  261. void tw_mas(char term[][50],char* str, int* p_long) {
  262. *p_long = 0;
  263. int k = 0;
  264. for (k = 0; k < strlen(str);) {
  265. int j = 0;
  266. if (isalpha(str[j + k])) {
  267. while (((j + k) < strlen(str)) && isalpha(str[j + k])) {
  268. term[*p_long][j] = str[j + k];
  269. j++;
  270. }
  271. term[*p_long][j] = '\0';
  272. (*p_long)++;
  273. k += j;
  274. }
  275. else
  276. if (str[k] == '(' || str[k] == ')' || str[k] == '+' || str[j + k] == '-' || str[j + k] == '*' || str[j + k] == '/') {
  277. term[*p_long][j] = str[k];
  278. term[*p_long][++j] = '\0';
  279. (*p_long)++;
  280. k++;
  281. }
  282. else
  283. if (isdigit(str[j + k])/*||str[k]=='.'||str[k]==','*/)
  284. {
  285. while (((j + k) < strlen(str)) && (isdigit(str[j + k])) /*|| str[k] == '.' || str[k] == ',')*/) {
  286. term[*p_long][j] = str[j + k];
  287. j++;
  288. }
  289. term[*p_long][j] = '\0';
  290. (*p_long)++;
  291. k += j;
  292. }
  293. else
  294. j = 0;
  295. }
  296. }
  297. //
  298.  
  299. bool findstr(char matr[][100], char* stroka, int p_longal) {
  300. int h = 0;
  301. int m_dlin = 0;
  302. for (int i = 0; i < p_longal; i++) {
  303. if (strcmp(matr[i], stroka) == 0) {
  304. return true;
  305. }
  306. }
  307. return false;
  308. }
  309.  
  310. void mas_alpha(char str1[][100], char term[][50], int p_long, int *p_longal) {
  311. *p_longal = 0;
  312.  
  313. for (int i = 0; i < p_long; i++)
  314. if (isalpha(term[i][0]) && findstr(str1, term[i], *p_longal)) {
  315. strcpy(str1[*p_longal], term[i]);//kuda ->
  316. (*p_longal)++;
  317. }
  318. }
  319.  
  320. void finds(char* str1[][100], char num[][100], int p_longal) {
  321.  
  322. for (int k = 0; k < p_longal; k++) {
  323. cout << "vvedite chislo " << str1[k] << endl;
  324. cin >> num[k];
  325. }
  326. }
  327. //
  328. void swaps(B_tree *MyTree, char(&str1)[][100], char (&num)[][100], int p_longal) {
  329. if (MyTree != nullptr) {
  330. Print_Obrat_obhod(MyTree->left);
  331. Print_Obrat_obhod(MyTree->right);
  332. cout << MyTree->per;
  333. if (isalpha(MyTree->per[0])) {
  334. for (int i = 0; i < p_longal; i++) {
  335. strcpy(str1[i], MyTree->per);
  336. strcpy(MyTree->per, num[i]);
  337. }
  338. }
  339. }
  340. }
  341.  
  342. int main() {
  343. setlocale(0, "russian");
  344. char str[100];
  345. int q=1;
  346. print_menu();
  347. while (q != 0) {
  348. cin >> q;
  349. switch (q)
  350. {
  351. case 0:
  352. {
  353. break;
  354. }
  355. case 1:
  356. {
  357. puts("введите выражения с числами, переменными и операциями *,/,+,-");
  358. cin>>str;
  359. // gets_s(str, 100);
  360. if (strlen(str) == 0) {
  361. puts("пустая строка");
  362. cout << endl << endl;
  363. print_menu();
  364. break;
  365. }
  366. puts("исходное выражение: ");
  367. puts(str);
  368. if (!Proverka(str)) {
  369. puts("Неверный ввод");
  370. puts("0-выход");
  371. puts("1-рандомное выражение");
  372. puts("2-исходное выражение (7/(a+3))/(4-(1+3*b))");
  373. break;
  374. }
  375. //cout << str;
  376. Un_operas(str);
  377. char term[50][50];
  378. int p_long = 0; // длина масива term
  379. tw_mas(term, str, &p_long);
  380. //cout<<endl << "Terms : " << p_long << endl;//это все разбиение на термы
  381. //for (int i = 0; i < p_long; i++)
  382. //cout << term[i] << endl;
  383. //cout << str;
  384. B_tree* MyTree = AddTree(term, 0,p_long-1);
  385. cout << "Tree" << endl;
  386. int lev = 0;
  387. Print_Tree(MyTree, lev);
  388. Print(MyTree);
  389. //find_sim(str);
  390. char* str1[100][100];
  391. int p_longal = 0;
  392. char num[100][100];
  393. finds(str1, num, p_longal);
  394. cout << endl << "выражение с числами\n" << endl;
  395. cout << str;
  396. //swaps(MyTree, str1, num, p_longal);
  397. cout << "Res=" << endl;
  398. Calculate(MyTree);
  399. break;
  400. }
  401. case 2:
  402. {
  403. strcpy(str, "(7/(a+3))/(4-(1+3*b))");
  404. puts("\nIshodnoe viragenie: ");
  405. puts(str);
  406. //find_sim(str);
  407. Un_operas(str);
  408. //cout << endl << "Выражение с числами" << endl;;
  409. cout << str;
  410. char term[50][50];
  411. int p_long = 0; // длина масива term
  412. tw_mas(term, str, &p_long);
  413. B_tree* MyTree = AddTree(term, 0, p_long - 1);
  414. Print(MyTree);
  415. break;
  416. }
  417. default:
  418. {
  419. cout << "Повторите выбор" << endl;
  420. print_menu();
  421. continue;
  422. }
  423. }
  424. //del_tree(MyTree);
  425. print_menu();
  426. }
  427. system("pause");
  428. return 0;
  429. }
  430. /*
  431. // присваивает значение в строке
  432. void swap(char* str, char* p_nam, int* p_value) {
  433. int k_bukv = strlen(p_nam);
  434. char* ishod_str;
  435. char* tmp = new char[100];
  436. char* num = new char[10];
  437. for (int i = 0; i < k_bukv; i++) {
  438. ishod_str = strchr(str, p_nam[i]);
  439. while (ishod_str)
  440. {
  441. strcpy(tmp, ishod_str + 1);
  442. for (int j = strlen(ishod_str); j >= 0; j--)
  443. ishod_str[j] = '\0';
  444. sprintf(num, "%d", p_value[i]);
  445. strcat(str, num);
  446. strcat(str, tmp);
  447. ishod_str = strchr(str, p_nam[i]);
  448.  
  449. }
  450. }
  451. delete[] tmp;
  452. delete[] num;
  453. }
  454. //найти одинаковые буквы ил нет, и присвоить им значение
  455. void find_sim(char *str) {
  456. int k_bukv = 0;
  457. for (int i = 0; i < strlen(str); i++) {
  458. if (isalpha(str[i])) {
  459. k_bukv++;
  460. }
  461. }
  462. if (k_bukv != 0) {
  463. int* p_value = new int[k_bukv];
  464. char* p_nam = new char[k_bukv];
  465. *p_nam = '\0';
  466. k_bukv = 0;
  467. for (int i = 0; i < strlen(str); i++)
  468. if (isalpha(str[i]) && !strchr(p_nam, str[i])) //если у нас буква и это первое вхождение в строку
  469. {
  470. //присоединяет не более n символов s2 к s1, завершает строку символом '\0', возвращает s1
  471. strncat(p_nam, str+i, 1);//vse simvols
  472. p_nam[k_bukv + 1] = '\0';
  473. k_bukv++;
  474. i++;
  475. while (isalpha(str[i])) {
  476. strncat(p_nam, str + i, 1);//vse simvols
  477. p_nam[k_bukv + 1] = '\0';
  478. k_bukv++;
  479. i++;
  480. }
  481. }
  482. cout << endl;
  483. for (int i = 0; i < strlen(p_nam); i++) {
  484.  
  485. cout << "введите число" << endl << p_nam[i] << " = ";
  486. cin >> p_value[i];
  487. cout << endl;
  488. }
  489.  
  490. swap(str, p_nam, p_value);
  491. }
  492.  
  493. }
  494. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement