Advertisement
Agrael

Untitled

Jan 8th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.94 KB | None | 0 0
  1. #include <iostream>
  2. #include <assert.h>
  3. #include <zconf.h>
  4.  
  5. using namespace std;
  6.  
  7. struct Node {
  8. int val;
  9. Node *next;
  10. };
  11.  
  12. Node *create_node(int value) {
  13. Node *new_node = new Node;
  14. new_node->val = value;
  15. new_node->next = nullptr;
  16. return new_node;
  17. }
  18.  
  19. void print_list(Node *first) {
  20. while(first != nullptr) {
  21. cout << first->val << " ";
  22. first = first->next;
  23. }
  24. cout << endl;
  25. }
  26.  
  27. Node * print_list_cycled(Node *first) {
  28. Node *tmp = first;
  29. do{
  30. cout << tmp->val << " ";
  31. tmp = tmp->next;
  32. } while(tmp != first);
  33. cout << endl;
  34. }
  35.  
  36. void print_list_cycled_test(Node *first) {
  37. Node *tmp = first;
  38. int i = 0;
  39. do{
  40. cout << tmp->val << " ";
  41. tmp = tmp->next;
  42. } while(++i < 12);
  43. cout << endl;
  44. }
  45.  
  46.  
  47. void linked_list_to_cycled(Node *&first) {
  48. Node *tmp = first;
  49. while(tmp->next != nullptr) tmp = tmp->next;
  50. tmp->next = first;
  51. }
  52.  
  53. void add_at_beginning(Node *&first, Node *new_node) {
  54. if(first == nullptr) {
  55. first = new_node;
  56. return;
  57. }
  58. new_node->next = first;
  59. first = new_node;
  60. }
  61.  
  62. void add_at_end(Node *&first, Node *new_node) {
  63. if(first == nullptr) {
  64. first = new_node;
  65. return;
  66. }
  67. Node *tmp_node = first;
  68. while(tmp_node->next != nullptr) tmp_node = tmp_node->next;
  69. tmp_node->next = new_node;
  70. }
  71.  
  72. /**********************************************************************************/
  73. /*
  74. * 2016/2017
  75. Dane są dwie listy cykliczne powstałe przez zapętlenie listy jednokierunkowej posortowanej
  76. rosnąco, dla każdej listy dany jest wskaźnik wskazujący przypadkowy element w takiej liście.
  77. Proszę napisać funkcję, która dla dwóch list cyklicznych, usuwa z obu list elementy
  78. występujące w obu listach. Do funkcji należy przekazać wskaźniki na dwie listy, funkcja
  79. powinna zwrócić łączną liczbę usuniętych elementów.
  80. Uwagi:
  81. - czas na rozwiązanie obu zadań wynosi 45 minut
  82. - za każde zadanie można otrzymać maksymalnie 5 pkt
  83. - oceniane będą: czytelność, poprawność i efektywność rozwiązań
  84. */
  85.  
  86. Node *get_last_cycled_sorted_list(Node *first) {
  87. Node *tmp = first;
  88. while(tmp->next != first and tmp->next->val >= tmp->val) tmp = tmp->next; // pierwszy warunek w petli jest zabezpieczeniem przed paroma nodeami o takiej samej wartości
  89. return tmp;
  90. }
  91.  
  92. void delete_next_nodes(Node *&first1, Node *&first2) {
  93. Node *tmp1, *tmp2;
  94. int val = first1->next->val;
  95. while(first1->next->val == val) { // usuwamy wszystkie elementy (czyli wszystkie kolejne) o tych samych wartościach
  96. tmp1 = first1->next;
  97. first1->next = first1->next->next;
  98. delete tmp1;
  99. }
  100. while(first2->next->val == val) {
  101. tmp2 = first2->next;
  102. first2->next = first2->next->next;
  103. delete tmp2;
  104. }
  105. }
  106. // idea - tak jak na zajęciach tyle że z tą różnicą, że otrzymujemy wskaźnik na ostatni element listy, dzięki czemu pierwszy (i każdy kolejny) możemy "obsłużyć" w jednej pętli.
  107. void zadanie2016A(Node *&list1, Node *&list2) {
  108. list1 = get_last_cycled_sorted_list(list1);
  109. list2 = get_last_cycled_sorted_list(list2);
  110. Node *first1 = list1;
  111. Node *first2 = list2;
  112. while(first1->next->val != list1->val or first2->next->val != list2->val) { // generalnie posługuję się ->next->val, a nie po prostu ->next, bo wartości ostatnich elementów mogą się powtarzać
  113. if(first1->next->val == first2->next->val) delete_next_nodes(first1, first2);
  114. else if(first1->next->val > first2->next->val) first2 = first2->next;
  115. else first1 = first1->next;
  116. }
  117. // sprawdzamy ostatni element (ewentualnie ostatnie elementy o tej samej wartości)
  118. if(first1->next->val == first2->next->val) delete_next_nodes(first1, first2);
  119.  
  120. list1 = first1->next;
  121. list2 = first2->next;
  122. }
  123.  
  124. /**********************************************************************************/
  125. /*
  126. Zbiór liczb naturalnych jest reprezentowany jako jednokierunkowa lista. Y-lista to struktura
  127. reprezentująca dwa zbiory liczb naturalnych (rysunek na wiki).
  128. Proszę napisać funkcję, która dwa zbiory A,B reprezentowane jako Y-lista przekształca w dwa
  129. zbiory reprezentowane jako niezależne listy. Do funkcji należy przekazać wskaźniki do dwóch
  130. list, funkcja powinna zwrócić liczbę elementów części wspólnej zbiorów A,B.
  131.  
  132. Uwagi:
  133. - ważne: jeżeli część wspólna dwóch zbiorów jest pusta, Y-lista staje się dwoma niezależnymi
  134. listami.
  135. - wartości w listach nie są uporządkowane
  136. */
  137.  
  138. struct Y_list {
  139. Node *branch1;
  140. Node *branch2;
  141. };
  142.  
  143. void connect_y_branches(Node *firstX, Node *first3) {
  144. while(firstX->next != nullptr) firstX = firstX->next;
  145. firstX->next = first3;
  146. }
  147. // tworzymy jakąś przykładową listę
  148. Y_list *create_y_list() {
  149. Y_list *y_list = new Y_list;
  150. y_list->branch1 = y_list->branch2 = nullptr;
  151. for(int i=0; i<3; i++) add_at_end(y_list->branch1, create_node(i));
  152. for(int i=0; i<5; i++) add_at_end(y_list->branch2, create_node(i));
  153. Node *common_branch = nullptr;
  154. for(int i=0; i<2; i++) add_at_end(common_branch, create_node(i));
  155. connect_y_branches(y_list->branch1, common_branch);
  156. connect_y_branches(y_list->branch2, common_branch);
  157. return y_list;
  158. }
  159.  
  160. int get_length(Node *first) {
  161. int length = 0;
  162. while(first) {
  163. length++;
  164. first = first->next;
  165. }
  166. return length;
  167. }
  168.  
  169. void move_forward(Node *&first, int i) {
  170. while(i > 0) {
  171. first = first->next;
  172. i--;
  173. }
  174. }
  175.  
  176. int zadanie2016B(Y_list *y_list, Node *&first1, Node *&first2) {
  177. if(y_list->branch1 == nullptr or y_list->branch2 == nullptr) return 0;
  178. first1 = y_list->branch1;
  179. first2 = y_list->branch2;
  180. int length_branch1 = get_length(first1), length_branch2 = get_length(first2);
  181. length_branch1 > length_branch2 ? move_forward(y_list->branch1, length_branch1 - length_branch2) : move_forward(y_list->branch2, length_branch2 - length_branch1);
  182.  
  183. while(y_list->branch1->next != y_list->branch2->next) {
  184. y_list->branch1 = y_list->branch1->next;
  185. y_list->branch2 = y_list->branch2->next;
  186. }
  187.  
  188. int count_elements = 0;
  189. while(y_list->branch1->next != nullptr) {
  190. count_elements++;
  191. y_list->branch2->next = create_node(y_list->branch1->next->val);
  192. y_list->branch1 = y_list->branch1->next;
  193. y_list->branch2 = y_list->branch2->next;
  194. }
  195. return count_elements;
  196. }
  197. // to tylko test, nie musicie się nim przejmować
  198. bool assert_zadanie2016B(Node *first1, Node *first2) {
  199. while(first1) {
  200. Node *tmp = first2;
  201. while(tmp) {
  202. if(tmp == first1) return false;
  203. tmp = tmp->next;
  204. }
  205.  
  206. first1 = first1->next;
  207. }
  208. return true;
  209. }
  210.  
  211. /**********************************************************************************/
  212. /*
  213. Dane są dwa jednokierunkowe łańcuchy odsyłaczowe (listy) zbudowane z elementów:
  214. struct node { int w; node* next; };
  215. Każdy łańcuch zawiera niepowtarzające się liczby naturalne. W obu łańcuchach liczby są posortowane rosnąco.
  216. Proszę napisać funkcję usuwającą z każdego łańcucha liczby nie występujące w drugim. Do funkcji należy przekazać
  217. wskazania na oba łańcuchy, funkcja powinna zwrócić łączną liczbę usuniętych elementów.
  218. */
  219.  
  220. void create_sample_lists_zadanie2014B(Node *&first1, Node *&first2) {
  221. for(int i = 0; i < 5; i++) add_at_end(first1, create_node(i));
  222. add_at_end(first1, create_node(10));
  223. for(int i = 3; i < 8; i++) add_at_end(first2, create_node(i));
  224. }
  225.  
  226. void delete_next_node(Node *&first, Node *&list) {
  227. Node *tmp = first->next;
  228. first->next = first->next->next;
  229. if(tmp == list) list = list->next; // jeżeli usuwamy z początku listy, to ją update'ujemy
  230. delete tmp;
  231. }
  232.  
  233. void zadanie2014B(Node *&list1, Node *&list2) {
  234. Node *first1 = new Node;
  235. Node *first2 = new Node;
  236. first1->next = list1; // tworzymy listy pomocnicze mające listy z parametrów na nextie, tak będzie łatwiej usuwać, bo nie będziemy musieli badać dodatkowo pierwszego elementu
  237. first2->next = list2;
  238. while(first1->next != nullptr or first2->next != nullptr) {
  239. if (first1->next == nullptr) delete_next_node(first2, list2); // sprawdzamy najpierw to z nullami, aby przypadekiem nie było "null strzałka równa się pałka". Jeżeli jedna lista jest już dalej nullem, to usuwamy kolejne elementy z tej drugiej
  240. else if(first2->next == nullptr) delete_next_node(first1, list1);
  241. else if(first1->next->val > first2->next->val) delete_next_node(first2, list2); // jeżeli któryś z elementów jest mniejszy, do go usuwamy
  242. else if(first1->next->val < first2->next->val) delete_next_node(first1, list1);
  243. else{ // jeżeli elementy są takie same, to je pomijamy i idziemy dalej
  244. first1 = first1->next;
  245. first2 = first2->next;
  246. }
  247. }
  248. }
  249.  
  250. /**********************************************************************************/
  251. /*
  252. * Dana jest lista jednokierunkowa zawierająca liczby naturalne. Liczbę oznaczamy jako niskobitową, jeśli w reprezentacji
  253. * binarnej liczba jedynek jest mniejsza niż 8, średniobitową, gdy liczba jedynek jest pomiędzy 8 a 24 a wysokobitową,
  254. * gdy liczba jedynek przekracza 24. Napisać funkcję, która podzieli listę na trzy listy z liczbami nisko, średnio i
  255. * wysokobitowymi, a następnie złączy te listy w jedną.
  256. */
  257.  
  258. int count_ones(int num) {
  259. int count = 0;
  260. while(num !=0) {
  261. if(num % 2 == 1) count++;
  262. num /= 2;
  263. }
  264. return count;
  265. }
  266.  
  267. void add_to_list(Node *&list, Node *new_node) {
  268. new_node->next = list;
  269. list = new_node;
  270. }
  271.  
  272. Node *merge_lists(Node *first1, Node *first2, Node *first3) {
  273. Node *first = nullptr;
  274. while(first1) {
  275. Node *tmp = first1;
  276. first1 = first1->next;
  277. add_to_list(first, tmp);
  278. }
  279. while(first2) {
  280. Node *tmp = first2;
  281. first2 = first2->next;
  282. add_to_list(first, tmp);
  283. }
  284. while(first3) {
  285. Node *tmp = first3;
  286. first3 = first3->next;
  287. add_to_list(first, tmp);
  288. }
  289. return first;
  290. }
  291.  
  292. void zadanie2011(Node *&first) {
  293. Node *lower = nullptr, *middle = nullptr, *upper = nullptr;
  294. while(first) {
  295. Node *tmp = first;
  296. first = first->next;
  297. int ones_amount = count_ones(tmp->val);
  298. if(ones_amount < 8) add_to_list(lower, tmp);
  299. else if(ones_amount <= 24) add_to_list(middle, tmp);
  300. else add_to_list(upper, tmp);
  301. }
  302. first = merge_lists(lower, middle, upper);
  303. }
  304.  
  305.  
  306. /**********************************************************************************/
  307.  
  308. int main() {
  309. Node *first = nullptr;
  310. for(int i=0; i<5; i++) add_at_end(first, create_node(i));
  311. print_list(first);
  312. linked_list_to_cycled(first);
  313. print_list_cycled_test(first);
  314. print_list_cycled(first);
  315. print_list_cycled(first->next->next);
  316. print_list_cycled(get_last_cycled_sorted_list(first->next->next));
  317. cout << endl;
  318.  
  319. cout << "zadanie z cyklicznymi:\n";
  320. // wklepuję do nich jakieś przykładowe dane
  321. Node *list1 = nullptr;
  322. Node *list2 = nullptr;
  323. for(int i = 0; i < 7; i++) {
  324. add_at_end(list1, create_node(i));
  325. }
  326. add_at_end(list2, create_node(2));
  327. for(int i = 1; i < 7; i++) {
  328. add_at_end(list2, create_node(2*i));
  329. }
  330. add_at_end(list1, create_node(18));
  331. add_at_end(list1, create_node(21));
  332. add_at_end(list1, create_node(21));
  333. add_at_end(list2, create_node(21));
  334.  
  335. linked_list_to_cycled(list1);
  336. linked_list_to_cycled(list2);
  337. print_list_cycled(list1);
  338. print_list_cycled(list2);
  339. list1 = list1->next->next;
  340. list2 = list2->next;
  341. zadanie2016A(list1, list2);
  342. print_list_cycled(list1);
  343. print_list_cycled(list2);
  344. cout << endl;
  345.  
  346. cout << "zadanie z y-listą\n";
  347. Node *first1 = nullptr;
  348. Node *first2 = nullptr;
  349. Y_list *y_list = create_y_list();
  350. print_list(y_list->branch1);
  351. print_list(y_list->branch2);
  352. cout << zadanie2016B(y_list, first1, first2) << endl;
  353. print_list(first1);
  354. print_list(first2);
  355. assert(assert_zadanie2016B(first1, first2));
  356. cout << endl;
  357.  
  358. cout << "trzecie zadanie:\n";
  359. Node *first3 = nullptr;
  360. Node *first4 = nullptr;
  361. create_sample_lists_zadanie2014B(first3, first4);
  362. print_list(first3);
  363. print_list(first4);
  364. zadanie2014B(first3, first4);
  365. print_list(first3);
  366. print_list(first4);
  367. cout << endl;
  368.  
  369. cout << "Zadanie z jedynkami bitowymi:\n";
  370. Node *first5 = nullptr;
  371. add_at_end(first5, create_node(1024));
  372. add_at_end(first5, create_node(1023));
  373. add_at_end(first5, create_node(2023));
  374. for(int i = 0; i < 10; i++) {
  375. add_at_end(first5, create_node(i));
  376. }
  377. print_list(first5);
  378. zadanie2011(first5);
  379. print_list(first5);
  380.  
  381. return 0;
  382. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement