Aaaaa988

lab3TI

Mar 7th, 2021
583
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //Первая часть практической работы
  2.  
  3. package ru.kiselev;
  4.  
  5. import java.io.*;
  6. import java.util.ArrayList;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9.  
  10. public class Lab1 {
  11.     static String FILE_NAME1 = "F1.txt";
  12.     static String FILE_NAME2 = "F2.txt";
  13.     // 0 - выкл 1 - вкл
  14.     static Integer DEBUG_MODE = 0;
  15.  
  16.  
  17.     public static void main(String[] args) throws IOException {
  18.         Map<String, Integer> frequencyDictionary1 = new HashMap<>();
  19.         Map<String, Integer> frequencyDictionary2 = new HashMap<>();
  20.         Map<String, Integer> frequencyDictionaryPair1 = new HashMap<>();
  21.         Map<String, Integer> frequencyDictionaryPair2 = new HashMap<>();
  22.  
  23.         writeF1(frequencyDictionary1);
  24.         writeF2(frequencyDictionary2);
  25.         frequencyDictionaryPair1 = counterPair(readFile(FILE_NAME1));
  26.         frequencyDictionaryPair2 = counterPair(readFile(FILE_NAME2));
  27.  
  28.         System.out.println("Entropy for F1 = " + shennon(probabilityCalculate(frequencyDictionary1)));
  29.         System.out.println("Entropy for F2 = " + shennon(probabilityCalculate(frequencyDictionary2)));
  30.         System.out.println("Entropy for pair F1 = " + shennon(probabilityCalculate(frequencyDictionaryPair1)) / 2);
  31.         System.out.println("Entropy for pair F2 = " + shennon(probabilityCalculate(frequencyDictionaryPair2)) / 2);
  32.  
  33.         // Считаем теоретическую вероятность
  34.         ArrayList temp = new ArrayList();
  35.         for (int i = 0; i < 4; i++) temp.add(0.25);
  36.         System.out.println("Theory entropy for F1 = " + shennon(temp));
  37.  
  38.         temp.clear();
  39.         temp.add(0.01);
  40.         temp.add(0.19);
  41.         temp.add(0.1);
  42.         temp.add(0.7);
  43.         System.out.println("Theory entropy for F2 = " + shennon(temp));
  44.  
  45.         temp.clear();
  46.         temp.add(0.0625);
  47.         temp.add(0.0625);
  48.         temp.add(0.0625);
  49.         temp.add(0.0625);
  50.         temp.add(0.0625);
  51.         temp.add(0.0625);
  52.         temp.add(0.0625);
  53.         temp.add(0.0625);
  54.         temp.add(0.0625);
  55.         temp.add(0.0625);
  56.         temp.add(0.0625);
  57.         temp.add(0.0625);
  58.         temp.add(0.0625);
  59.         temp.add(0.0625);
  60.         temp.add(0.0625);
  61.         temp.add(0.0625);
  62.         System.out.println("Theory entropy for pair F1 = " + (shennon(temp) / 2));
  63.  
  64.         temp.clear();
  65.         temp.add(0.0001);
  66.         temp.add(0.0019);
  67.         temp.add(0.001);
  68.         temp.add(0.007);
  69.         temp.add(0.0019);
  70.         temp.add(0.0361);
  71.         temp.add(0.019);
  72.         temp.add(0.133);
  73.         temp.add(0.001);
  74.         temp.add(0.019);
  75.         temp.add(0.01);
  76.         temp.add(0.07);
  77.         temp.add(0.007);
  78.         temp.add(0.133);
  79.         temp.add(0.07);
  80.         temp.add(0.49);
  81.         System.out.printf("Theory entropy for pair F2 = " + (shennon(temp) / 2));
  82.     }
  83.  
  84.     /**
  85.      * Считывает файл в одну строку
  86.      * @param filename имя считываемого файла (путь к файлу)
  87.      * @return все содержимое файла в строке
  88.      */
  89.     static String readFile(String filename) {
  90.         StringBuffer result = new StringBuffer();
  91.  
  92.         try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
  93.             String temp;
  94.             while ((temp = reader.readLine()) != null) {
  95.                 result.append(temp);
  96.             }
  97.         } catch (FileNotFoundException e) {
  98.             e.printStackTrace();
  99.         } catch (IOException e) {
  100.             e.printStackTrace();
  101.         }
  102.  
  103.         return result.toString();
  104.     }
  105.  
  106.     /**
  107.      * Считает вхождения всех пар символов (соседних друг с другом)
  108.      * @param strFile строка, в которой нужно посчитать пары символов
  109.      * @return Map пар символов и их количество в строке
  110.      * @throws IOException
  111.      */
  112.     public static Map<String, Integer> counterPair(String strFile) throws IOException {
  113.         Map<String, Integer> frequencyDictionaryPair = new HashMap<>();
  114.  
  115.         for (int i = 0; i < strFile.length() - 1; i++) {
  116.             merge(frequencyDictionaryPair, strFile.charAt(i) + "" + strFile.charAt(i + 1));
  117.         }
  118.  
  119.         return frequencyDictionaryPair;
  120.     }
  121.  
  122.     /**
  123.      * Вычисляет фактические вероятности
  124.      * @param frequencyDictionary количество определенных символов или их последовательностей
  125.      * @return ArrayList полученных вероятностей
  126.      */
  127.     public static ArrayList probabilityCalculate(Map<String, Integer> frequencyDictionary) {
  128.         ArrayList<Double> probability = new ArrayList<>();
  129.         int generalCount = 0;
  130.  
  131.         for (Map.Entry<String, Integer> symbol : frequencyDictionary.entrySet()) {
  132.             generalCount += symbol.getValue();
  133.         }
  134.  
  135.         for (Map.Entry<String, Integer> symbol : frequencyDictionary.entrySet()) {
  136.             probability.add(symbol.getValue().doubleValue() / generalCount);
  137.             if (DEBUG_MODE == 1) {
  138.                 System.out.println(symbol.getKey() + " " + symbol.getValue() + " " + (symbol.getValue().doubleValue() / generalCount));
  139.             }
  140.         }
  141.         if (DEBUG_MODE == 1)
  142.         System.out.println(frequencyDictionary.size());
  143.  
  144.         return probability;
  145.     }
  146.  
  147.     /**
  148.      * Метод считает число вхождений любого числа символов
  149.      * @param strFile строка для подсчета вхождений символов
  150.      * @param quantity количество символов для подсчета
  151.      * @return Map символов и их количества в строке
  152.      * @throws IOException
  153.      */
  154.     public static Map<String, Integer> counterUniversal(String strFile, int quantity) throws IOException {
  155.         Map<String, Integer> frequencyDictionary = new HashMap<>();
  156.  
  157.         for (int i = 0; i < strFile.length() - quantity; i++) {
  158.             StringBuilder temp = new StringBuilder();
  159.             for (int j = 0; j < quantity; j++) {
  160.                 temp.append(strFile.charAt(i + j) + "");
  161.             }
  162.             merge(frequencyDictionary, temp.toString());
  163.         }
  164.  
  165.         return frequencyDictionary;
  166.     }
  167.  
  168.     public static double shennon(ArrayList<Double> probability) {
  169.         double entropy = 0;
  170.  
  171.         for (Double p : probability) {
  172.             entropy += p * (Math.log(p) / Math.log(2));
  173.         }
  174.  
  175.         return -entropy;
  176.     }
  177.  
  178.     /**
  179.      * Генерирует в файл равновероятную последовательность из четырех символов
  180.      * @param frequencyDictionary1 словарь для посчета количества каждого символа
  181.      * @throws IOException
  182.      */
  183.     private static void writeF1(Map<String, Integer> frequencyDictionary1) throws IOException {
  184.         File file = new File(FILE_NAME1);
  185.         FileWriter writer = new FileWriter(file);
  186.  
  187.         int rnd;
  188.  
  189.         while (file.length() < 10000) {
  190.             for (int i = 0; i < 1024; i++) {
  191.                 rnd = (int) (Math.random() * 4);
  192.  
  193.                 writer.append((char) (rnd + 65));
  194.                 merge(frequencyDictionary1, (char) (rnd + 65) + ""); // счетчик символов
  195.             }
  196.             writer.flush();
  197.         }
  198.     }
  199.  
  200.     /**
  201.      * Последовательно и независимо генерирует символы с определенными вероятностями и записывает их в файл
  202.      * @param frequencyDictionary2 словарь для посчета количества каждого символа
  203.      * @throws IOException
  204.      */
  205.     private static void writeF2(Map<String, Integer> frequencyDictionary2) throws IOException {
  206.         File file = new File(FILE_NAME2);
  207.         FileWriter writer = new FileWriter(file);
  208.  
  209.         int rnd;
  210.         while (file.length() < 10000) {
  211.             for (int i = 0; i < 1024; i++) {
  212.                 rnd = (int) (Math.random() * 100 + 1);
  213.  
  214.                 if (rnd <= 1) {
  215.                     writer.append((char) 65); // вероятность 0.01
  216.                     merge(frequencyDictionary2, (char) 65 + "");
  217.                 } else if (rnd > 1 && rnd <= 20) {
  218.                     writer.append((char) 66); // вероятность 0.19
  219.                     merge(frequencyDictionary2, (char) 66 + "");
  220.                 } else if (rnd > 20 && rnd <= 30) {
  221.                     writer.append((char) 67); //вероятность 0.1
  222.                     merge(frequencyDictionary2, (char) 67 + "");
  223.                 } else if (rnd > 30) {
  224.                     writer.append((char) 68); // вероятноть 0.7
  225.                     merge(frequencyDictionary2, (char) 68 + "");
  226.                 }
  227.             }
  228.             writer.flush();
  229.         }
  230.     }
  231.  
  232.     public static void merge(Map<String, Integer> map, String symbol) {
  233.         if (map.containsKey(symbol)) {
  234.             int oldCount = map.get(symbol);
  235.             map.put(symbol, ++oldCount);
  236.         } else {
  237.             map.put(symbol, 1);
  238.         }
  239.     }
  240. }
  241.  
  242. //Вторая часть практической работы
  243.  
  244. package ru.kiselev;
  245.  
  246. import java.io.IOException;
  247. import java.util.HashMap;
  248. import java.util.Map;
  249.  
  250. public class Lab2 extends Lab1{
  251.     static String FILE_NAME = "The Stand.txt";
  252.  
  253.     public static void main(String[] args) throws IOException {
  254. //        DEBUG_MODE = 1;
  255.  
  256.         String strFile = readFile(FILE_NAME);
  257.         String clearStrFile = clearStr(strFile).toString();
  258.  
  259.         Map<String, Integer> frequencyDictionary = counterSingle(clearStrFile);
  260.         Map<String, Integer> frequencyDictionaryPair = counterPair(clearStrFile);
  261.  
  262.         System.out.println("Entropy for single symbol = " + shennon(probabilityCalculate(frequencyDictionary)));
  263.         System.out.println("Entropy for pair symbols = " + shennon(probabilityCalculate(frequencyDictionaryPair)) / 2);
  264.  
  265.         for (int i = 1; i <= 2; i++) {
  266.             System.out.println("Entropy for " + i + "th symbol(s) = " + shennon(probabilityCalculate(counterUniversal(clearStrFile, i))) / i);
  267.         }
  268.     }
  269.  
  270.     /**
  271.      * Метод возвращает строку, очищенную от всего кроме диапазона A-Z и пробела
  272.      * Если в строке встречаются прописные (a-z), заменяет их на заглавные
  273.      * Остальные символы (знаки препинания и тд) пропускаются
  274.      * @param oldStr исходная строка
  275.      * @return чистая строка
  276.      */
  277.     public static StringBuilder clearStr(String oldStr) {
  278.         StringBuilder result = new StringBuilder();
  279.  
  280.         for (int i = 0; i < oldStr.length(); i++) {
  281.             Character symbol = oldStr.charAt(i);
  282.             // от A до Z (заглавных) или пробел
  283.             if ((Integer.valueOf(symbol) >= 65 && Integer.valueOf(symbol) <= 90) || Integer.valueOf(symbol) == 32) {
  284.                 result.append(symbol);
  285.             } else if (Integer.valueOf(symbol) >= 97 && Integer.valueOf(symbol) <= 122) {
  286.                 result.append((char) (symbol - 32));
  287.             }
  288.         }
  289.         return result;
  290.     }
  291.  
  292.     /**
  293.      * Метод считает число вхождений каждого символа
  294.      * @param strFile строка для подсчета вхождений символов
  295.      * @return Map символов и их количества в строке
  296.      * @throws IOException
  297.      */
  298.     public static Map<String, Integer> counterSingle(String strFile) throws IOException {
  299.         Map<String, Integer> frequencyDictionary = new HashMap<>();
  300.  
  301.         for (int i = 0; i < strFile.length(); i++) {
  302.             merge(frequencyDictionary, strFile.charAt(i) + "");
  303.         }
  304.  
  305.         return frequencyDictionary;
  306.     }
  307. }
  308.  
  309. //Третья часть практической работы
  310.  
  311. package ru.kiselev;
  312.  
  313. import java.io.BufferedReader;
  314. import java.io.FileNotFoundException;
  315. import java.io.FileReader;
  316. import java.io.IOException;
  317.  
  318. public class Lab3 extends Lab2 {
  319.     static final String FILE_NAME = "src/ru/kiselev/Lab1.java";
  320.  
  321.     public static void main(String[] args) throws IOException {
  322.        DEBUG_MODE = 1;
  323.  
  324.         String strFile = readCodeFile(FILE_NAME);
  325.  
  326.         for (int i = 1; i <= 5; i++) {
  327.             System.out.println("Энтропия для " + i + " символа(ов) = " + shennon(probabilityCalculate(counterUniversal(strFile, i))) / i);
  328.         }
  329.     }
  330.  
  331.     /**
  332.      * Считывание файла с кодом без комментариев, документации и вывода на экран
  333.      * @param filename имя файла
  334.      * @return считанный файл в String
  335.      */
  336.     static String readCodeFile(String filename) {
  337.         StringBuffer result = new StringBuffer();
  338.  
  339.         try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
  340.             String temp;
  341.             while ((temp = reader.readLine()) != null) {
  342.                 if (isComment(temp)) {
  343.                     if (DEBUG_MODE == 1) {
  344.                         System.out.println("Строка '" + temp + "' содержит комментарии или вывод на экран");
  345.                     }
  346.                 } else {
  347.                     result.append(temp);
  348.                 }
  349.             }
  350.         } catch (FileNotFoundException e) {
  351.             e.printStackTrace();
  352.         } catch (IOException e) {
  353.             e.printStackTrace();
  354.         }
  355.  
  356.         return result.toString();
  357.     }
  358.  
  359.     /**
  360.      * Проверяет, является ли строка комментарием, документацией или выводом на экран
  361.      * @param str строка для проверки
  362.      * @return true - является, false - не является
  363.      */
  364.     static boolean isComment(String str) {
  365.         if (deleteWhiteSpace(str).startsWith("/**") ||
  366.                 deleteWhiteSpace(str).startsWith("*") ||
  367.                 deleteWhiteSpace(str).startsWith("*/") ||
  368.                 deleteWhiteSpace(str).startsWith("//") ||
  369.                 deleteWhiteSpace(str).startsWith("System.out.println")) {
  370.             return true;
  371.         } else {
  372.             return false;
  373.         }
  374.     }
  375.  
  376.     /**
  377.      * Возвращает строку без пробелов
  378.      * @param s строка на вход
  379.      * @return строка s без пробелов
  380.      */
  381.     static String deleteWhiteSpace(String s) {
  382.         return s.replaceAll("\\s+", "");
  383.     }
  384. }
  385.  
RAW Paste Data