Aaaaa988

lab2 TI

Feb 28th, 2021
68
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package ru.labs;
  2.  
  3. import java.io.IOException;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6.  
  7. public class Lab2 extends Lab1{
  8. static String FILE_NAME = "The Picture of Dorian Gray.txt";
  9.  
  10. public static void main(String[] args) throws IOException {
  11. DEBUG_MODE = 1;
  12.  
  13. String strFile = readFile(FILE_NAME);
  14. String clearStrFile = clearStr(strFile).toString();
  15.  
  16. Map<String, Integer> frequencyDictionary = counterSingle(clearStrFile);
  17. Map<String, Integer> frequencyDictionaryPair = counterPair(clearStrFile);
  18.  
  19. System.out.println("Энтропия одиночных символов = " + shennon(probabilityCalculate(frequencyDictionary)));
  20. System.out.println("Энтропия парных символов = " + shennon(probabilityCalculate(frequencyDictionaryPair)) / 2);
  21. }
  22.  
  23. /**
  24. * Метод возвращает строку, очищенную от всего кроме диапазона A-Z и пробела
  25. * Если в строке встречаются прописные (a-z), заменяет их на заглавные
  26. * Остальные символы (знаки препинания и тд) пропускаются
  27. * @param oldStr исходная строка
  28. * @return чистая строка
  29. */
  30. public static StringBuilder clearStr(String oldStr) {
  31. StringBuilder result = new StringBuilder();
  32.  
  33. for (int i = 0; i < oldStr.length(); i++) {
  34. Character symbol = oldStr.charAt(i);
  35. // от A до Z (заглавных) или пробел
  36. if ((Integer.valueOf(symbol) >= 65 && Integer.valueOf(symbol) <= 90) || Integer.valueOf(symbol) == 32) {
  37. result.append(symbol);
  38. } else if (Integer.valueOf(symbol) >= 97 && Integer.valueOf(symbol) <= 122) {
  39. result.append((char) (symbol - 32));
  40. }
  41. }
  42. return result;
  43. }
  44.  
  45. /**
  46. * Метод считает число вхождений каждого символа
  47. * @param strFile строка для подсчета вхождений символов
  48. * @return Map символов и их количества в строке
  49. * @throws IOException
  50. */
  51. public static Map<String, Integer> counterSingle(String strFile) throws IOException {
  52. Map<String, Integer> frequencyDictionary = new HashMap<>();
  53.  
  54. for (int i = 0; i < strFile.length(); i++) {
  55. merge(frequencyDictionary, strFile.charAt(i) + "");
  56. }
  57.  
  58. return frequencyDictionary;
  59. }
  60. }
  61.  
  62.  
  63. package ru.labs;
  64.  
  65. import java.io.*;
  66. import java.util.ArrayList;
  67. import java.util.HashMap;
  68. import java.util.Map;
  69.  
  70. public class Lab1 {
  71. static String FILE_NAME1 = "F1.txt";
  72. static String FILE_NAME2 = "F2.txt";
  73. // 0 - выкл 1 - вкл
  74. static Integer DEBUG_MODE = 1;
  75.  
  76.  
  77. public static void main(String[] args) throws IOException {
  78. Map<String, Integer> frequencyDictionary1 = new HashMap<>();
  79. Map<String, Integer> frequencyDictionary2 = new HashMap<>();
  80. Map<String, Integer> frequencyDictionaryPair1 = new HashMap<>();
  81. Map<String, Integer> frequencyDictionaryPair2 = new HashMap<>();
  82.  
  83. writeF1(frequencyDictionary1);
  84. writeF2(frequencyDictionary2);
  85. frequencyDictionaryPair1 = counterPair(readFile(FILE_NAME1));
  86. frequencyDictionaryPair2 = counterPair(readFile(FILE_NAME2));
  87.  
  88. System.out.println("Entropy for F1 = " + shennon(probabilityCalculate(frequencyDictionary1)));
  89. System.out.println("Entropy for F2 = " + shennon(probabilityCalculate(frequencyDictionary2)));
  90. System.out.println("Entropy for pair F1 = " + shennon(probabilityCalculate(frequencyDictionaryPair1)) / 2);
  91. System.out.println("Entropy for pair F2 = " + shennon(probabilityCalculate(frequencyDictionaryPair2)) / 2);
  92.  
  93. // Считаем теоретическую вероятность
  94. ArrayList temp = new ArrayList();
  95. for (int i = 0; i < 4; i++) temp.add(0.25);
  96. System.out.println("Theory entropy for F1 = " + shennon(temp));
  97.  
  98. temp.clear();
  99. temp.add(0.01);
  100. temp.add(0.19);
  101. temp.add(0.1);
  102. temp.add(0.7);
  103. System.out.println("Theory entropy for F2 = " + shennon(temp));
  104.  
  105. temp.clear();
  106. temp.add(0.0625);
  107. temp.add(0.0625);
  108. temp.add(0.0625);
  109. temp.add(0.0625);
  110. temp.add(0.0625);
  111. temp.add(0.0625);
  112. temp.add(0.0625);
  113. temp.add(0.0625);
  114. temp.add(0.0625);
  115. temp.add(0.0625);
  116. temp.add(0.0625);
  117. temp.add(0.0625);
  118. temp.add(0.0625);
  119. temp.add(0.0625);
  120. temp.add(0.0625);
  121. temp.add(0.0625);
  122. System.out.println("Theory entropy for pair F1 = " + (shennon(temp) / 2));
  123.  
  124. temp.clear();
  125. temp.add(0.0001);
  126. temp.add(0.0019);
  127. temp.add(0.001);
  128. temp.add(0.007);
  129. temp.add(0.0019);
  130. temp.add(0.0361);
  131. temp.add(0.019);
  132. temp.add(0.133);
  133. temp.add(0.001);
  134. temp.add(0.019);
  135. temp.add(0.01);
  136. temp.add(0.07);
  137. temp.add(0.007);
  138. temp.add(0.133);
  139. temp.add(0.07);
  140. temp.add(0.49);
  141. System.out.printf("Theory entropy for pair F2 = " + (shennon(temp) / 2));
  142. }
  143.  
  144. /**
  145. * Считывает файл в одну строку
  146. * @param filename имя считываемого файла (путь к файлу)
  147. * @return все содержимое файла в строке
  148. */
  149. static String readFile(String filename) {
  150. StringBuffer result = new StringBuffer();
  151.  
  152. try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
  153. String temp;
  154. while ((temp = reader.readLine()) != null) {
  155. result.append(temp);
  156. }
  157. } catch (FileNotFoundException e) {
  158. e.printStackTrace();
  159. } catch (IOException e) {
  160. e.printStackTrace();
  161. }
  162.  
  163. return result.toString();
  164. }
  165.  
  166. /**
  167. * Считает вхождения всех пар символов (соседних друг с другом)
  168. * @param strFile строка, в которой нужно посчитать пары символов
  169. * @return Map пар символов и их количество в строке
  170. * @throws IOException
  171. */
  172. public static Map<String, Integer> counterPair(String strFile) throws IOException {
  173. Map<String, Integer> frequencyDictionaryPair = new HashMap<>();
  174.  
  175. for (int i = 0; i < strFile.length() - 1; i++) {
  176. merge(frequencyDictionaryPair, strFile.charAt(i) + "" + strFile.charAt(i + 1));
  177. }
  178.  
  179. return frequencyDictionaryPair;
  180. }
  181.  
  182. /**
  183. * Вычисляет фактические вероятности
  184. * @param frequencyDictionary количество определенных символов или их последовательностей
  185. * @return ArrayList полученных вероятностей
  186. */
  187. public static ArrayList probabilityCalculate(Map<String, Integer> frequencyDictionary) {
  188. ArrayList<Double> probability = new ArrayList<>();
  189. int generalCount = 0;
  190.  
  191. for (Map.Entry<String, Integer> symbol : frequencyDictionary.entrySet()) {
  192. generalCount += symbol.getValue();
  193. }
  194.  
  195. for (Map.Entry<String, Integer> symbol : frequencyDictionary.entrySet()) {
  196. probability.add(symbol.getValue().doubleValue() / generalCount);
  197. if (DEBUG_MODE == 1) {
  198. System.out.println(symbol.getKey() + " " + symbol.getValue() + " " + (symbol.getValue().doubleValue() / generalCount));
  199. }
  200. }
  201.  
  202. return probability;
  203. }
  204.  
  205. public static double shennon(ArrayList<Double> probability) {
  206. double entropy = 0;
  207.  
  208. for (Double p : probability) {
  209. entropy += p * (Math.log(p) / Math.log(2));
  210. }
  211.  
  212. return -entropy;
  213. }
  214.  
  215. /**
  216. * Генерирует в файл равновероятную последовательность из четырех символов
  217. * @param frequencyDictionary1 словарь для посчета количества каждого символа
  218. * @throws IOException
  219. */
  220. private static void writeF1(Map<String, Integer> frequencyDictionary1) throws IOException {
  221. File file = new File(FILE_NAME1);
  222. FileWriter writer = new FileWriter(file);
  223.  
  224. int rnd;
  225.  
  226. while (file.length() < 10000) {
  227. for (int i = 0; i < 1024; i++) {
  228. rnd = (int) (Math.random() * 4);
  229.  
  230. writer.append((char) (rnd + 65));
  231. merge(frequencyDictionary1, (char) (rnd + 65) + ""); // счетчик символов
  232. }
  233. writer.flush();
  234. }
  235. }
  236.  
  237. /**
  238. * Последовательно и независимо генерирует символы с определенными вероятностями и записывает их в файл
  239. * @param frequencyDictionary2 словарь для посчета количества каждого символа
  240. * @throws IOException
  241. */
  242. private static void writeF2(Map<String, Integer> frequencyDictionary2) throws IOException {
  243. File file = new File(FILE_NAME2);
  244. FileWriter writer = new FileWriter(file);
  245.  
  246. int rnd;
  247. while (file.length() < 10000) {
  248. for (int i = 0; i < 1024; i++) {
  249. rnd = (int) (Math.random() * 100 + 1);
  250.  
  251. if (rnd <= 1) {
  252. writer.append((char) 65); // вероятность 0.01
  253. merge(frequencyDictionary2, (char) 65 + "");
  254. } else if (rnd > 1 && rnd <= 20) {
  255. writer.append((char) 66); // вероятность 0.19
  256. merge(frequencyDictionary2, (char) 66 + "");
  257. } else if (rnd > 20 && rnd <= 30) {
  258. writer.append((char) 67); //вероятность 0.1
  259. merge(frequencyDictionary2, (char) 67 + "");
  260. } else if (rnd > 30) {
  261. writer.append((char) 68); // вероятноть 0.7
  262. merge(frequencyDictionary2, (char) 68 + "");
  263. }
  264. }
  265. writer.flush();
  266. }
  267. }
  268.  
  269. public static void merge(Map<String, Integer> map, String symbol) {
  270. if (map.containsKey(symbol)) {
  271. int oldCount = map.get(symbol);
  272. map.put(symbol, ++oldCount);
  273. } else {
  274. map.put(symbol, 1);
  275. }
  276. }
  277. }
  278.  
RAW Paste Data