Advertisement
THOMAS_SHELBY_18

lesson03

Mar 16th, 2024 (edited)
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 17.22 KB | Source Code | 0 0
  1. package by.it.group351004.narivonchik.lesson03;
  2.  
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.util.*;
  6.  
  7. //Lesson 3. A_Huffman.
  8. //Разработайте метод encode(File file) для кодирования строки (код Хаффмана)
  9.  
  10. // По данным файла (непустой строке ss длины не более 104104),
  11. // состоящей из строчных букв латинского алфавита,
  12. // постройте оптимальный по суммарной длине беспрефиксный код.
  13.  
  14. // Используйте Алгоритм Хаффмана — жадный алгоритм оптимального
  15. // безпрефиксного кодирования алфавита с минимальной избыточностью.
  16.  
  17. // В первой строке выведите количество различных букв kk,
  18. // встречающихся в строке, и размер получившейся закодированной строки.
  19. // В следующих kk строках запишите коды букв в формате "letter: code".
  20. // В последней строке выведите закодированную строку. Примеры ниже
  21.  
  22. //        Sample Input 1:
  23. //        a
  24. //
  25. //        Sample Output 1:
  26. //        1 1
  27. //        a: 0
  28. //        0
  29.  
  30. //        Sample Input 2:
  31. //        abacabad
  32. //
  33. //        Sample Output 2:
  34. //        4 14
  35. //        a: 0
  36. //        b: 10
  37. //        c: 110
  38. //        d: 111
  39. //        01001100100111
  40.  
  41. public class A_Huffman {
  42.  
  43.     //Изучите классы Node InternalNode LeafNode
  44.     abstract class Node implements Comparable<Node> {
  45.         //абстрактный класс элемент дерева
  46.         //(сделан abstract, чтобы нельзя было использовать его напрямую)
  47.         //а только через его версии InternalNode и LeafNode
  48.         private final int frequence; //частота символов
  49.  
  50.         //генерация кодов (вызывается на корневом узле
  51.         //один раз в конце, т.е. после построения дерева)
  52.         abstract void fillCodes(String code);
  53.  
  54.         //конструктор по умолчанию
  55.         private Node(int frequence) {
  56.             this.frequence = frequence;
  57.         }
  58.  
  59.         //метод нужен для корректной работы узла в приоритетной очереди
  60.         //или для сортировок
  61.         @Override
  62.         public int compareTo(Node o) {
  63.             return Integer.compare(frequence, o.frequence);
  64.         }
  65.     }
  66.  
  67.     ////////////////////////////////////////////////////////////////////////////////////
  68.     //расширение базового класса до внутреннего узла дерева
  69.     private class InternalNode extends Node {
  70.         //внутренный узел дерева
  71.         Node left;  //левый ребенок бинарного дерева
  72.         Node right; //правый ребенок бинарного дерева
  73.  
  74.         //для этого дерева не существует внутренних узлов без обоих детей
  75.         //поэтому вот такого конструктора будет достаточно
  76.         InternalNode(Node left, Node right) {
  77.             super(left.frequence + right.frequence);
  78.             this.left = left;
  79.             this.right = right;
  80.         }
  81.  
  82.         @Override
  83.         void fillCodes(String code) {
  84.             left.fillCodes(code + "0");
  85.             right.fillCodes(code + "1");
  86.         }
  87.  
  88.     }
  89.  
  90.     ////////////////////////////////////////////////////////////////////////////////////
  91.     //расширение базового класса до листа дерева
  92.     private class LeafNode extends Node {
  93.         //лист
  94.         char symbol; //символы хранятся только в листах
  95.  
  96.         LeafNode(int frequence, char symbol) {
  97.             super(frequence);
  98.             this.symbol = symbol;
  99.         }
  100.  
  101.         @Override
  102.         void fillCodes(String code) {
  103.             //добрались до листа, значит рекурсия закончена, код уже готов
  104.             //и можно запомнить его в индексе для поиска кода по символу.
  105.             codes.put(this.symbol, code);
  106.         }
  107.     }
  108.  
  109.     //индекс данных из листьев
  110.     static private Map<Character, String> codes = new TreeMap<>();
  111.  
  112.  
  113.     //!!!!!!!!!!!!!!!!!!!!!!!!!     НАЧАЛО ЗАДАЧИ     !!!!!!!!!!!!!!!!!!!!!!!!!
  114.     String encode(File file) throws FileNotFoundException {
  115.         //прочитаем строку для кодирования из тестового файла
  116.         Scanner scanner = new Scanner(file);
  117.         String s = scanner.next();
  118.  
  119.         //все комментарии от тестового решения были оставлены т.к. это задание A.
  120.         //если они вам мешают их можно удалить
  121.  
  122.         Map<Character, Integer> count = new HashMap<>();
  123.         //1. переберем все символы по очереди и рассчитаем их частоту в Map count
  124.             //для каждого символа добавим 1 если его в карте еще нет или инкремент если есть.
  125.         char c;
  126.         for (int i = 0; i < s.length(); i++) {
  127.             boolean isThisElement = false;
  128.             for(Map.Entry<Character, Integer> entry: count.entrySet()) {
  129.                 c = entry.getKey();
  130.                 if (s.charAt(i) == c) {
  131.                     isThisElement = true;
  132.                     count.put(c, entry.getValue()+1);
  133.                     break;
  134.                 }
  135.             }
  136.             if (!isThisElement)
  137.                     count.put(s.charAt(i), 1);
  138.         }
  139.  
  140.         //2. перенесем все символы в приоритетную очередь в виде листьев
  141.         PriorityQueue<Node> priorityQueue = new PriorityQueue<>();
  142.         for(Map.Entry<Character, Integer> entry: count.entrySet()) {
  143.             Node symbol = new LeafNode (entry.getValue(), entry.getKey());
  144.             priorityQueue.add(symbol);
  145.         }
  146.  
  147.         //3. вынимая по два узла из очереди (для сборки родителя)
  148.         //и возвращая этого родителя обратно в очередь
  149.         //построим дерево кодирования Хаффмана.
  150.         //У родителя частоты детей складываются.
  151.         while (priorityQueue.size() > 1) {
  152.             Node leftSymbol = priorityQueue.remove();
  153.             Node rightSymbol = priorityQueue.remove();
  154.             Node parentsSymbol = new InternalNode(leftSymbol, rightSymbol);
  155.             priorityQueue.add(parentsSymbol);
  156.         }
  157.  
  158.         //4. последний из родителей будет корнем этого дерева
  159.         //это будет последний и единственный элемент оставшийся в очереди priorityQueue.
  160.         StringBuilder sb = new StringBuilder();
  161.         Node root = priorityQueue.remove();
  162.         root.fillCodes("");
  163.         for (int i = 0; i < s.length(); i++) {
  164.             sb.append(codes.get(s.charAt(i)));
  165.         }
  166.  
  167.         return sb.toString();
  168.         //01001100100111
  169.         //01001100100111
  170.     }
  171.     //!!!!!!!!!!!!!!!!!!!!!!!!!     КОНЕЦ ЗАДАЧИ     !!!!!!!!!!!!!!!!!!!!!!!!!
  172.  
  173.  
  174.     public static void main(String[] args) throws FileNotFoundException {
  175.         String root = System.getProperty("user.dir") + "/src/";
  176.         File f = new File(root + "by/it/a_khmelev/lesson03/dataHuffman.txt");
  177.         A_Huffman instance = new A_Huffman();
  178.         long startTime = System.currentTimeMillis();
  179.         String result = instance.encode(f);
  180.         long finishTime = System.currentTimeMillis();
  181.         System.out.printf("%d %d\n", codes.size(), result.length());
  182.         for (Map.Entry<Character, String> entry : codes.entrySet()) {
  183.             System.out.printf("%s: %s\n", entry.getKey(), entry.getValue());
  184.         }
  185.         System.out.println(result);
  186.     }
  187.  
  188. }
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200. package by.it.group351004.narivonchik.lesson03;
  201.  
  202. import java.io.File;
  203. import java.io.FileNotFoundException;
  204. import java.util.Map;
  205. import java.util.Scanner;
  206. import java.util.TreeMap;
  207.  
  208. // Lesson 3. B_Huffman.
  209. // Восстановите строку по её коду и беспрефиксному коду символов.
  210.  
  211. // В первой строке входного файла заданы два целых числа
  212. // kk и ll через пробел — количество различных букв, встречающихся в строке,
  213. // и размер получившейся закодированной строки, соответственно.
  214. //
  215. // В следующих kk строках записаны коды букв в формате "letter: code".
  216. // Ни один код не является префиксом другого.
  217. // Буквы могут быть перечислены в любом порядке.
  218. // В качестве букв могут встречаться лишь строчные буквы латинского алфавита;
  219. // каждая из этих букв встречается в строке хотя бы один раз.
  220. // Наконец, в последней строке записана закодированная строка.
  221. // Исходная строка и коды всех букв непусты.
  222. // Заданный код таков, что закодированная строка имеет минимальный возможный размер.
  223. //
  224. //        Sample Input 1:
  225. //        1 1
  226. //        a: 0
  227. //        0
  228.  
  229. //        Sample Output 1:
  230. //        a
  231.  
  232.  
  233. //        Sample Input 2:
  234. //        4 14
  235. //        a: 0
  236. //        b: 10
  237. //        c: 110
  238. //        d: 111
  239. //        01001100100111
  240.  
  241. //        Sample Output 2:
  242. //        abacabad
  243.  
  244. public class B_Huffman {
  245.  
  246.     String decode(File file) throws FileNotFoundException {
  247.         StringBuilder result=new StringBuilder();
  248.         //прочитаем строку для кодирования из тестового файла
  249.         Scanner scanner = new Scanner(file);
  250.         Integer count = scanner.nextInt();
  251.         Integer length = scanner.nextInt();
  252.         scanner.nextLine();
  253.         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! НАЧАЛО ЗАДАЧИ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
  254.         Map<String, Character> codes = new TreeMap<>();
  255.         String str;
  256.         char symbol;
  257.         String code;
  258.  
  259.         for (int i = 0; i < count; i++){
  260.             str = scanner.nextLine();
  261.             symbol = str.charAt(0);
  262.             code = str.substring(3);
  263.             codes.put(code, symbol);
  264.         }
  265.         String encodedStr = scanner.nextLine();
  266.         int nowIndex = 0;
  267.         int startCodeIndex = 0;
  268.         while (nowIndex < length){
  269.             if (encodedStr.charAt(nowIndex) == '0'){
  270.                 result.append(codes.get(encodedStr.substring(startCodeIndex, nowIndex+1)));
  271.                 startCodeIndex = nowIndex+1;
  272.             }
  273.             nowIndex++;
  274.         }
  275.         if(encodedStr.charAt(nowIndex-1) != '0')
  276.             result.append(codes.get(encodedStr.substring(startCodeIndex, nowIndex)));
  277.         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! КОНЕЦ ЗАДАЧИ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
  278.         return result.toString(); //01001100100111
  279.     }
  280.  
  281.     public static void main(String[] args) throws FileNotFoundException {
  282.         String root = System.getProperty("user.dir") + "/src/";
  283.         File f = new File(root + "by/it/a_khmelev/lesson03/encodeHuffman.txt");
  284.         B_Huffman instance = new B_Huffman();
  285.         String result = instance.decode(f);
  286.         System.out.println(result);
  287.     }
  288.  
  289.  
  290. }
  291.  
  292.  
  293.  
  294.  
  295.  
  296. package by.it.group351004.narivonchik.lesson03;
  297.  
  298. import java.io.FileInputStream;
  299. import java.io.FileNotFoundException;
  300. import java.io.InputStream;
  301. import java.util.ArrayList;
  302. import java.util.List;
  303. import java.util.Scanner;
  304.  
  305. // Lesson 3. C_Heap.
  306. // Задача: построить max-кучу = пирамиду = бинарное сбалансированное дерево на массиве.
  307. // ВАЖНО! НЕЛЬЗЯ ИСПОЛЬЗОВАТЬ НИКАКИЕ КОЛЛЕКЦИИ, КРОМЕ ARRAYLIST (его можно, но только для массива)
  308.  
  309. //      Проверка проводится по данным файла
  310. //      Первая строка входа содержит число операций 1 ≤ n ≤ 100000.
  311. //      Каждая из последующих nn строк задают операцию одного из следующих двух типов:
  312.  
  313. //      Insert x, где 0 ≤ x ≤ 1000000000 — целое число;
  314. //      ExtractMax.
  315.  
  316. //      Первая операция добавляет число x в очередь с приоритетами,
  317. //      вторая — извлекает максимальное число и выводит его.
  318.  
  319. //      Sample Input:
  320. //      6
  321. //      Insert 200
  322. //      Insert 10
  323. //      ExtractMax
  324. //      Insert 5
  325. //      Insert 500
  326. //      ExtractMax
  327. //
  328. //      Sample Output:
  329. //      200
  330. //      500
  331.  
  332.  
  333. public class C_HeapMax {
  334.  
  335.     private class MaxHeap {
  336.         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! НАЧАЛО ЗАДАЧИ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
  337.         //тут запишите ваше решение.
  338.         //Будет мало? Ну тогда можете его собрать как Generic и/или использовать в варианте B
  339.         private List<Long> heap = new ArrayList<>();
  340.  
  341.         int siftDown(int i) {
  342.             while (i < (heap.size() - 1) / 2) {
  343.                 int left = 2 * i + 1;
  344.                 int right = 2 * i + 2;
  345.                 int max = left;
  346.                 if((right < heap.size()) && (heap.get(right) > heap.get(left)))
  347.                     max = right;
  348.                 if(i == max)
  349.                     break;
  350.                 swap(i, max);
  351.                 i = max;
  352.             }
  353.             return i;
  354.         }
  355.  
  356.         int siftUp(int i) {
  357.             while (heap.get(i) > heap.get((i - 1) / 2)){
  358.                 swap(i, (i - 1) / 2);
  359.                 i = (i - 1) / 2;
  360.             }
  361.             return i;
  362.         }
  363.  
  364.         void insert(Long value) { //вставка
  365.             heap.add(value);
  366.             siftUp(heap.size() - 1);
  367.         }
  368.  
  369.         Long extractMax() { //извлечение и удаление максимума
  370.             Long result;
  371.             result = heap.get(0);
  372.             heap.remove(0);
  373.             siftDown(0);
  374.             return result;
  375.         }
  376.  
  377.         private void swap(int i, int j){
  378.             Long temp = heap.get(j);
  379.             heap.set(j, heap.get(i));
  380.             heap.set(i, temp);
  381.         }
  382.         //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! КОНЕЦ ЗАДАЧИ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
  383.     }
  384.  
  385.     //эта процедура читает данные из файла, ее можно не менять.
  386.     Long findMaxValue(InputStream stream) {
  387.         Long maxValue=0L;
  388.         MaxHeap heap = new MaxHeap();
  389.         //прочитаем строку для кодирования из тестового файла
  390.         Scanner scanner = new Scanner(stream);
  391.         Integer count = scanner.nextInt();
  392.         for (int i = 0; i < count; ) {
  393.             String s = scanner.nextLine();
  394.             if (s.equalsIgnoreCase("extractMax")) {
  395.                 Long res=heap.extractMax();
  396.                 if (res!=null && res>maxValue) maxValue=res;
  397.                 System.out.println();
  398.                 i++;
  399.             }
  400.             if (s.contains(" ")) {
  401.                 String[] p = s.split(" ");
  402.                 if (p[0].equalsIgnoreCase("insert"))
  403.                     heap.insert(Long.parseLong(p[1]));
  404.                 i++;
  405.             //System.out.println(heap); //debug
  406.             }
  407.         }
  408.         return maxValue;
  409.     }
  410.  
  411.     public static void main(String[] args) throws FileNotFoundException {
  412.         String root = System.getProperty("user.dir") + "/src/";
  413.         InputStream stream = new FileInputStream(root + "by/it/a_khmelev/lesson03/heapData.txt");
  414.         C_HeapMax instance = new C_HeapMax();
  415.         System.out.println("MAX="+instance.findMaxValue(stream));
  416.     }
  417.  
  418.     // РЕМАРКА. Это задание исключительно учебное.
  419.     // Свои собственные кучи нужны довольно редко.
  420.     // "В реальном бою" все существенно иначе. Изучите и используйте коллекции
  421.     // TreeSet, TreeMap, PriorityQueue и т.д. с нужным CompareTo() для объекта внутри.
  422. }
  423.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement