Guest User

Untitled

a guest
Dec 18th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.16 KB | None | 0 0
  1. /*********************************************************************
  2. LZ 77, 78, W Algorithms
  3. -------------------
  4. _
  5. ___ ___ __| | ___ _____ ___ __ ___
  6. / __/ _ \ / _` |/ _ \ / _ \ \/ / '_ \ / _ \
  7. | (_| (_) | (_| | __/ | __/> <| |_) | (_) |
  8. \___\___/ \__,_|\___| \___/_/\_\ .__/ \___/
  9. |_|
  10.  
  11. Made with love in Code Expo lab
  12. www.code-expo.com
  13. created by : ENG, Majed Sief Al-Nasr
  14.  
  15. **********************************************************************/
  16.  
  17. #include <iostream>
  18. #include <string>
  19. #include <vector>
  20. #include <sstream>
  21. #include "windows.h"
  22.  
  23. using namespace std;
  24.  
  25. struct Node{
  26. int index;
  27. string data;
  28. Node *next;
  29. };
  30.  
  31. void st_Node(Node *head, int index, string data){
  32. head->index = index;
  33. head->data = data;
  34. head->next = NULL;
  35. }
  36.  
  37. void insert_Node(Node *head, int index, string data){
  38. Node *new_Node = new Node;
  39. new_Node->index = index;
  40. new_Node->data = data;
  41. new_Node->next = NULL;
  42.  
  43. Node *curr = head;
  44. while (curr != NULL)
  45. {
  46. if (curr->next == NULL)
  47. {
  48. curr->next = new_Node;
  49. return;
  50. }
  51. curr = curr->next;
  52. }
  53. }
  54.  
  55. Node *search_Node(Node *head, string data)
  56. {
  57. Node *curr = head;
  58. while (curr != NULL)
  59. {
  60. if (data.compare(curr->data) == 0)
  61. return curr;
  62. else
  63. curr = curr->next;
  64. }
  65. return NULL;
  66. }
  67.  
  68. Node *search_Node(Node *head, int index)
  69. {
  70. Node *curr = head;
  71. while (curr != NULL)
  72. {
  73. if (index == curr->index)
  74. return curr;
  75. else
  76. curr = curr->next;
  77. }
  78. return NULL;
  79. }
  80.  
  81. bool delete_Node(Node *head, Node *to_delete){
  82. if (to_delete == NULL)
  83. return false;
  84. else if (to_delete == head)
  85. {
  86. head = to_delete->next;
  87. delete to_delete;
  88. return true;
  89. }
  90. else{
  91. Node *curr = head;
  92. while (curr)
  93. {
  94. if (curr->next == to_delete)
  95. {
  96. curr->next = to_delete->next;
  97. delete to_delete;
  98. return true;
  99. }
  100. curr = curr->next;
  101. }
  102. return false;
  103. }
  104. }
  105.  
  106. vector <string> split(string str, char delimiter) {
  107. vector<string> internal;
  108. stringstream ss(str); // Turn the string into a stream.
  109. string tok;
  110.  
  111. while (getline(ss, tok, delimiter)) {
  112. internal.push_back(tok);
  113. }
  114.  
  115. return internal;
  116. }
  117.  
  118. string LZ77(string input, int option);
  119. string LZ78(string input, int option);
  120. string LZW(string input, int option);
  121.  
  122. int main()
  123. {
  124. string input, result, method_text;
  125. int method, option, option2;
  126.  
  127. string intro = R"(
  128. Hi I'm Alpha ^_^ , Code Expo's assistant, I'm here to help you.
  129. )";
  130. cout << intro;
  131. main_menu:
  132. string main_menu = R"(
  133. -------------------------------------------------------------------------------
  134. This tool generate compression and decompression using LZ-77, LZ-78 and LZW methods :
  135.  
  136. 1- LZ-77
  137. 2- LZ-78
  138. 3- LZW
  139.  
  140. Enter 1, 2 or 3 according to method.
  141. > )"; cout << main_menu;
  142.  
  143. cin >> method;
  144.  
  145. if (method == 1)
  146. method_text = "LZ-77";
  147. else if (method == 2)
  148. method_text = "LZ-78";
  149. else if (method == 3)
  150. method_text = "LZW";
  151. else
  152. {
  153. system("cls");
  154. cout << intro;
  155. goto main_menu;
  156. }
  157.  
  158. method_menu:
  159. system("cls");
  160. cout << intro;
  161.  
  162. string main_menu_2 = R"(
  163. -------------------------------------------------------------------------------
  164. This tool generate compression and decompression using )" + method_text + R"( method :
  165.  
  166. 1- Compression
  167. 2- Decompression
  168.  
  169. 0- Main menu
  170.  
  171. Enter 1, 2 or 0 according to method.
  172. > )"; cout << main_menu_2;
  173.  
  174. cin >> option;
  175.  
  176. if (option == 1)
  177. {
  178. system("cls");
  179. cout << intro;
  180.  
  181. string lz77_Compression = R"(
  182. -------------------------------------------------------------------------------
  183. )" + method_text + R"( > Compression :)";
  184. cout << lz77_Compression << endl;
  185.  
  186. cout << "\t Enter your phrases : ";
  187. cin.ignore();
  188. getline(cin, input);
  189. if (method == 1)
  190. result = LZ77(input, 1);
  191. else if (method == 2)
  192. result = LZ78(input, 1);
  193. else if (method == 3)
  194. result = LZW(input, 1);
  195. else
  196. {
  197. system("cls");
  198. cout << intro;
  199. goto main_menu;
  200. }
  201.  
  202. cout << "\n\t Final result : " << result << endl;
  203.  
  204. back_1:
  205. cout << "\n Enter 0 to back to Main menu or 1 to back to Method menu. \n > ";
  206. cin >> option2;
  207.  
  208. if (option2 == 0)
  209. {
  210. system("cls");
  211. cout << intro;
  212. goto main_menu;
  213. }
  214. else if (option2 == 1)
  215. goto method_menu;
  216. else
  217. goto back_1;
  218. }
  219. else if (option == 2)
  220. {
  221. system("cls");
  222. cout << intro;
  223.  
  224. string lz77_Compression = R"(
  225. -------------------------------------------------------------------------------
  226. LZ-77 > Decompression :)";
  227. cout << lz77_Compression << endl;
  228. cout << "Note : Enter 0 for NULL characters\n\n";
  229. cout << "\t Enter your code : ";
  230. cin.ignore();
  231. getline(cin, input);
  232. if (method == 1)
  233. result = LZ77(input, 2);
  234. else if (method == 2)
  235. result = LZ78(input, 2);
  236. else if (method == 3)
  237. result = LZW(input, 2);
  238. else
  239. main_menu;
  240.  
  241. cout << "\n\t Final result : " << result << endl;
  242.  
  243. back_2:
  244. cout << "\n Enter 0 to back to Main menu or 1 to back to Method menu. \n > ";
  245. cin >> option2;
  246.  
  247. if (option2 == 0)
  248. {
  249. system("cls");
  250. cout << intro;
  251. goto main_menu;
  252. }
  253. else if (option2 == 1)
  254. goto method_menu;
  255. else
  256. goto back_2;
  257.  
  258. }
  259. else if (option == 0)
  260. {
  261. system("cls");
  262. cout << intro;
  263. goto main_menu;
  264. }
  265. else
  266. goto method_menu;
  267.  
  268.  
  269. cin.get();
  270. cin.ignore();
  271. return 0;
  272. }
  273.  
  274. string LZ77(string input, int option)
  275. {
  276. // Initialized variables
  277. string result;
  278. int length, char_info_selc = 0;
  279.  
  280. if (option == 1)
  281. {
  282. check_char: // Length checker pointer
  283. length = (int)input.length(); // Calculate input string length
  284. // Check input line length is less than 3
  285. if (length <= 2)
  286. {
  287. cout << "enter at leaset 3 characters \n";
  288. getline(cin, input); // Read input string
  289. goto check_char;
  290. }
  291.  
  292. // Declare an arry for final result called 'result_ary'
  293. int** result_ary = new int*[3];
  294. for (int i = 0; i < length; ++i)
  295. result_ary[i] = new int[length];
  296. // Set result_ary elements value to 0 to prevent previous values
  297. for (int i = 0; i < 3; i++)
  298. {
  299. for (int j = 0; j < length; j++)
  300. result_ary[i][j] = 0;
  301. }
  302.  
  303. // Declare an arry to store every char info in input string called 'char_info'
  304. int** char_info = new int*[3];
  305. for (int i = 0; i < length; ++i)
  306. char_info[i] = new int[length];
  307. // Set char_info elements value to 0 to prevent previous values
  308. for (int i = 0; i < 3; i++)
  309. {
  310. for (int j = 0; j < length; j++)
  311. char_info[i][j] = 0;
  312. }
  313.  
  314. // Set first char info to (0,0,'<first char>')
  315. result_ary[0][0] = 0;
  316. result_ary[1][0] = 0;
  317. result_ary[2][0] = input[0];
  318.  
  319. // Set result counter
  320. int result_count = 1;
  321.  
  322. // A loop to perform some operations in every char in input string
  323. for (int i = 1; i < length; i++)
  324. {
  325. // A loop to check input char in position i is equal to any of
  326. // previous char in input and save this info in char_info array
  327. for (int j = 0; j < i; j++)
  328. {
  329. // Check position of previous view of element i
  330. if (input[i] == input[j])
  331. {
  332. // Set position pointer
  333. char_info[0][char_info_selc] = i - j;
  334.  
  335. // Increase char info array selector by 1
  336. char_info_selc++;
  337. }
  338.  
  339. }
  340.  
  341. // A loop to check length for every char position
  342. for (int j = 0; j < length; j++)
  343. {
  344. // Check current char info array position is not equal to 0
  345. if (char_info[0][j] != 0)
  346. {
  347. // Set start point
  348. int start = i - char_info[0][j];
  349.  
  350. // Set count to calculate length for this char position
  351. int count = 1;
  352.  
  353. // A loop to check length for this char position
  354. for (int k = 0; k < length; k++)
  355. {
  356. // Check next element of start by next element of input
  357. if (input[start + count] == input[i + count])
  358. count++; // Increase count by 1
  359. else
  360. {
  361. char_info[1][j] = count; // Store count value in length
  362.  
  363. // Check if this input char is the last char
  364. if (i != (length - 1))
  365. {
  366. // Store next char to char info
  367. // Check this postion is equal to length
  368. if (char_info[0][j] + count == length)
  369. char_info[2][j] = 0; // Set 0 in next char field
  370. else
  371. char_info[2][j] = input[char_info[0][j] + count]; // Set the next char
  372. }
  373. else
  374. char_info[2][j] = NULL; // Set NULL in next char field
  375.  
  376. break; // Stop loop
  377. }
  378. }
  379. }
  380. }
  381.  
  382. // Set large selector
  383. int large = 0; // large selector equal 0
  384.  
  385. // Loop to check the largest length for every char info
  386. for (int k = 1; k < length; k++)
  387. {
  388. // Check largest
  389. if (char_info[1][large] == char_info[1][k])
  390. large = k; // Set largest
  391. else if (char_info[1][large] < char_info[1][k])
  392. large = k; // Set largest
  393. }
  394.  
  395. // Check largest length is equal to 0
  396. if (char_info[1][large] == 0)
  397. char_info[2][large] = input[i]; // Set char info
  398. else
  399. {
  400. i += char_info[1][large]; // increase loop counter by length of the largest char info element
  401. char_info[2][large] = input[i]; // Set char info
  402. }
  403.  
  404. // Set final result info
  405. result_ary[0][result_count] = char_info[0][large];
  406. result_ary[1][result_count] = char_info[1][large];
  407. result_ary[2][result_count] = char_info[2][large];
  408.  
  409. // Increase result counter
  410. result_count++;
  411.  
  412. // Prepare char info array for next char by set it to 0
  413. for (int z = 0; z < 2; z++)
  414. {
  415. for (int j = 0; j < length; j++)
  416. char_info[z][j] = 0; // Set every element in char info to 0
  417. }
  418.  
  419. // Prepare char info selector for next char by set it to 0
  420. char_info_selc = 0;
  421. }
  422.  
  423. // Display final results
  424. for (int j = 0; j < length; j++)
  425. {
  426. if (result_ary[0][j] == 0 && result_ary[1][j] == 0)
  427. {
  428. if (result_ary[2][j] != NULL || result_ary[2][j] != 0)
  429. {
  430. char z = result_ary[2][j];
  431. result += to_string(result_ary[0][j]) + "," + to_string(result_ary[1][j]) + "," + z + " ";
  432. }
  433. }
  434. else
  435. {
  436. char z = result_ary[2][j];
  437. result += to_string(result_ary[0][j]) + "," + to_string(result_ary[1][j]) + "," + z + " ";
  438. }
  439. }
  440.  
  441. // Clean up memory
  442. //for (int i = 0; i < 3; ++i) {
  443. // {
  444. // delete[] result_ary[i]; delete[] char_info[i];
  445. // }
  446. //}
  447. //delete[] result_ary;
  448. //delete[] char_info;
  449.  
  450. return result;
  451. }
  452. else if (option == 2)
  453. {
  454. vector<string> s_input = split(input, ' ');
  455.  
  456. for (int i = 0; i < s_input.size(); ++i)
  457. {
  458. vector<string> ss_input = split(s_input[i], ',');
  459.  
  460. int p = stoi(ss_input[0]),
  461. l = stoi(ss_input[1]);
  462. string ch;
  463. if (ss_input[2][0] == '0')
  464. ch = ' ';
  465. else
  466. ch = ss_input[2];
  467.  
  468. if (p != 0)
  469. {
  470. int result_len = (int)result.length();
  471. for (int x = 0; x < l; x++)
  472. result += result[result_len - p + x];
  473. }
  474.  
  475. if (ch[0] != '0' || ch[0] != NULL)
  476. result += ch;
  477. }
  478. return result;
  479. }
  480. }
  481.  
  482. string LZ78(string input, int option)
  483. {
  484. if (option == 1)
  485. {
  486. Node *dictionary = new Node;
  487. string word, result;
  488. int length, last_seen, index = 1;
  489.  
  490. length = (int)input.length();
  491. word = input[0];
  492. st_Node(dictionary, 1, word);
  493. result += "0," + word;
  494.  
  495. for (int i = 1; i < length; i++)
  496. {
  497. string data;
  498. data = input[i];
  499.  
  500. re_check:
  501. Node *search = search_Node(dictionary, data);
  502.  
  503. if (search)
  504. {
  505. i++;
  506. data += input[i];
  507. last_seen = search->index;
  508. goto re_check;
  509. }
  510. else
  511. {
  512. char zero;
  513. if (input[i] == ' ')
  514. zero = '0';
  515. else
  516. zero = input[i];
  517.  
  518. if ((int)data.length() < 2)
  519. result += " " + to_string(0) + "," + zero;
  520. else
  521. result += " " + to_string(last_seen) + "," + zero;
  522.  
  523. index++;
  524. if (i != length)
  525. insert_Node(dictionary, index, data);
  526. }
  527. }
  528.  
  529. return result;
  530. }
  531. if (option == 2)
  532. {
  533. Node *dictionary = new Node;
  534. string result;
  535.  
  536. vector <string> s_input = split(input, ' ');
  537. int zz = 2;
  538. for (int i = 0; i < s_input.size(); i++)
  539. {
  540. vector <string> ss_input = split(s_input[i], ',');
  541.  
  542. if (i == 0)
  543. {
  544. st_Node(dictionary, 1, ss_input[1]);
  545. result += ss_input[1];
  546. }
  547. else
  548. {
  549. Node *serched;
  550. string get_search = ss_input[1];
  551. serched = search_Node(dictionary, stoi(ss_input[0]));
  552. if (serched)
  553. {
  554. result += serched->data + get_search;
  555. get_search = serched->data + split(s_input[i], ',')[1];
  556. insert_Node(dictionary, zz, get_search);
  557. }
  558. else
  559. {
  560. if (stoi(ss_input[0]) == 0)
  561. insert_Node(dictionary, zz, get_search);
  562. else
  563. insert_Node(dictionary, zz, get_search);
  564.  
  565. result += get_search;
  566. }
  567. zz++;
  568. }
  569. }
  570.  
  571. if (result[(int)result.length() - 1] == '0')
  572. result = result.substr(0, result.size() - 1);
  573.  
  574. return result;
  575. }
  576. }
  577.  
  578. string LZW(string input, int option)
  579. {
  580. if (option == 1)
  581. {
  582. Node *dictionary = new Node;
  583. string result;
  584. int length, last_seen, index = 128;
  585.  
  586. st_Node(dictionary, 32, " ");
  587. for (int i = 33; i < 128; i++)
  588. {
  589. string data;
  590. data = i;
  591. insert_Node(dictionary, i, data);
  592. }
  593.  
  594. length = (int)input.length();
  595.  
  596. for (int i = 0; i < length; i++)
  597. {
  598. Node *searched;
  599. string search;
  600. search = input[i];
  601.  
  602. re_search:
  603. searched = search_Node(dictionary, search);
  604. if (searched)
  605. {
  606. i++;
  607. search += input[i];
  608. last_seen = searched->index;
  609. if (i != length)
  610. goto re_search;
  611. else
  612. goto print;
  613. }
  614. else
  615. {
  616. insert_Node(dictionary, index, search);
  617. index++;
  618. print:
  619. result += to_string(last_seen) + " ";
  620. i--;
  621. }
  622. }
  623.  
  624. return result;
  625. }
  626. if (option == 2)
  627. {
  628. Node *dictionary = new Node;
  629. string result;
  630. int index = 128;
  631.  
  632. st_Node(dictionary, 32, " ");
  633. for (int i = 33; i < 128; i++)
  634. {
  635. string data;
  636. data = i;
  637. insert_Node(dictionary, i, data);
  638. }
  639.  
  640. vector <string> s_input = split(input, ' ');
  641. for (int i = 0; i < s_input.size(); i++)
  642. {
  643. Node *searched;
  644. int search;
  645. search = stoi(s_input[i]);
  646.  
  647. searched = search_Node(dictionary, search);
  648.  
  649. string cur, prev, data;
  650. if (searched)
  651. cur = search_Node(dictionary, stoi(s_input[i]))->data;
  652. if (i != 0)
  653. prev = search_Node(dictionary, stoi(s_input[i - 1]))->data;
  654. else
  655. prev = cur;
  656.  
  657. int show = 0;
  658. if (searched)
  659. {
  660. result += searched->data;
  661.  
  662. if (i != 0)
  663. {
  664. data = prev + cur[0];
  665. if (show != 1)
  666. {
  667. insert_Node(dictionary, index, data);
  668. index++;
  669. }
  670. }
  671. show = 0;
  672. }
  673. else
  674. {
  675. data = prev + prev[0];
  676. insert_Node(dictionary, index, data);
  677. index++;
  678. show = 1;
  679. result += data;
  680. }
  681. }
  682.  
  683. return result;
  684. }
  685. }
Add Comment
Please, Sign In to add comment