Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package ru.labs;
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.Map;
- public class Lab2 extends Lab1{
- static String FILE_NAME = "The Picture of Dorian Gray.txt";
- public static void main(String[] args) throws IOException {
- DEBUG_MODE = 1;
- String strFile = readFile(FILE_NAME);
- String clearStrFile = clearStr(strFile).toString();
- Map<String, Integer> frequencyDictionary = counterSingle(clearStrFile);
- Map<String, Integer> frequencyDictionaryPair = counterPair(clearStrFile);
- System.out.println("Энтропия одиночных символов = " + shennon(probabilityCalculate(frequencyDictionary)));
- System.out.println("Энтропия парных символов = " + shennon(probabilityCalculate(frequencyDictionaryPair)) / 2);
- }
- /**
- * Метод возвращает строку, очищенную от всего кроме диапазона A-Z и пробела
- * Если в строке встречаются прописные (a-z), заменяет их на заглавные
- * Остальные символы (знаки препинания и тд) пропускаются
- * @param oldStr исходная строка
- * @return чистая строка
- */
- public static StringBuilder clearStr(String oldStr) {
- StringBuilder result = new StringBuilder();
- for (int i = 0; i < oldStr.length(); i++) {
- Character symbol = oldStr.charAt(i);
- // от A до Z (заглавных) или пробел
- if ((Integer.valueOf(symbol) >= 65 && Integer.valueOf(symbol) <= 90) || Integer.valueOf(symbol) == 32) {
- result.append(symbol);
- } else if (Integer.valueOf(symbol) >= 97 && Integer.valueOf(symbol) <= 122) {
- result.append((char) (symbol - 32));
- }
- }
- return result;
- }
- /**
- * Метод считает число вхождений каждого символа
- * @param strFile строка для подсчета вхождений символов
- * @return Map символов и их количества в строке
- * @throws IOException
- */
- public static Map<String, Integer> counterSingle(String strFile) throws IOException {
- Map<String, Integer> frequencyDictionary = new HashMap<>();
- for (int i = 0; i < strFile.length(); i++) {
- merge(frequencyDictionary, strFile.charAt(i) + "");
- }
- return frequencyDictionary;
- }
- }
- package ru.labs;
- import java.io.*;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Map;
- public class Lab1 {
- static String FILE_NAME1 = "F1.txt";
- static String FILE_NAME2 = "F2.txt";
- // 0 - выкл 1 - вкл
- static Integer DEBUG_MODE = 1;
- public static void main(String[] args) throws IOException {
- Map<String, Integer> frequencyDictionary1 = new HashMap<>();
- Map<String, Integer> frequencyDictionary2 = new HashMap<>();
- Map<String, Integer> frequencyDictionaryPair1 = new HashMap<>();
- Map<String, Integer> frequencyDictionaryPair2 = new HashMap<>();
- writeF1(frequencyDictionary1);
- writeF2(frequencyDictionary2);
- frequencyDictionaryPair1 = counterPair(readFile(FILE_NAME1));
- frequencyDictionaryPair2 = counterPair(readFile(FILE_NAME2));
- System.out.println("Entropy for F1 = " + shennon(probabilityCalculate(frequencyDictionary1)));
- System.out.println("Entropy for F2 = " + shennon(probabilityCalculate(frequencyDictionary2)));
- System.out.println("Entropy for pair F1 = " + shennon(probabilityCalculate(frequencyDictionaryPair1)) / 2);
- System.out.println("Entropy for pair F2 = " + shennon(probabilityCalculate(frequencyDictionaryPair2)) / 2);
- // Считаем теоретическую вероятность
- ArrayList temp = new ArrayList();
- for (int i = 0; i < 4; i++) temp.add(0.25);
- System.out.println("Theory entropy for F1 = " + shennon(temp));
- temp.clear();
- temp.add(0.01);
- temp.add(0.19);
- temp.add(0.1);
- temp.add(0.7);
- System.out.println("Theory entropy for F2 = " + shennon(temp));
- temp.clear();
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- temp.add(0.0625);
- System.out.println("Theory entropy for pair F1 = " + (shennon(temp) / 2));
- temp.clear();
- temp.add(0.0001);
- temp.add(0.0019);
- temp.add(0.001);
- temp.add(0.007);
- temp.add(0.0019);
- temp.add(0.0361);
- temp.add(0.019);
- temp.add(0.133);
- temp.add(0.001);
- temp.add(0.019);
- temp.add(0.01);
- temp.add(0.07);
- temp.add(0.007);
- temp.add(0.133);
- temp.add(0.07);
- temp.add(0.49);
- System.out.printf("Theory entropy for pair F2 = " + (shennon(temp) / 2));
- }
- /**
- * Считывает файл в одну строку
- * @param filename имя считываемого файла (путь к файлу)
- * @return все содержимое файла в строке
- */
- static String readFile(String filename) {
- StringBuffer result = new StringBuffer();
- try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
- String temp;
- while ((temp = reader.readLine()) != null) {
- result.append(temp);
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return result.toString();
- }
- /**
- * Считает вхождения всех пар символов (соседних друг с другом)
- * @param strFile строка, в которой нужно посчитать пары символов
- * @return Map пар символов и их количество в строке
- * @throws IOException
- */
- public static Map<String, Integer> counterPair(String strFile) throws IOException {
- Map<String, Integer> frequencyDictionaryPair = new HashMap<>();
- for (int i = 0; i < strFile.length() - 1; i++) {
- merge(frequencyDictionaryPair, strFile.charAt(i) + "" + strFile.charAt(i + 1));
- }
- return frequencyDictionaryPair;
- }
- /**
- * Вычисляет фактические вероятности
- * @param frequencyDictionary количество определенных символов или их последовательностей
- * @return ArrayList полученных вероятностей
- */
- public static ArrayList probabilityCalculate(Map<String, Integer> frequencyDictionary) {
- ArrayList<Double> probability = new ArrayList<>();
- int generalCount = 0;
- for (Map.Entry<String, Integer> symbol : frequencyDictionary.entrySet()) {
- generalCount += symbol.getValue();
- }
- for (Map.Entry<String, Integer> symbol : frequencyDictionary.entrySet()) {
- probability.add(symbol.getValue().doubleValue() / generalCount);
- if (DEBUG_MODE == 1) {
- System.out.println(symbol.getKey() + " " + symbol.getValue() + " " + (symbol.getValue().doubleValue() / generalCount));
- }
- }
- return probability;
- }
- public static double shennon(ArrayList<Double> probability) {
- double entropy = 0;
- for (Double p : probability) {
- entropy += p * (Math.log(p) / Math.log(2));
- }
- return -entropy;
- }
- /**
- * Генерирует в файл равновероятную последовательность из четырех символов
- * @param frequencyDictionary1 словарь для посчета количества каждого символа
- * @throws IOException
- */
- private static void writeF1(Map<String, Integer> frequencyDictionary1) throws IOException {
- File file = new File(FILE_NAME1);
- FileWriter writer = new FileWriter(file);
- int rnd;
- while (file.length() < 10000) {
- for (int i = 0; i < 1024; i++) {
- rnd = (int) (Math.random() * 4);
- writer.append((char) (rnd + 65));
- merge(frequencyDictionary1, (char) (rnd + 65) + ""); // счетчик символов
- }
- writer.flush();
- }
- }
- /**
- * Последовательно и независимо генерирует символы с определенными вероятностями и записывает их в файл
- * @param frequencyDictionary2 словарь для посчета количества каждого символа
- * @throws IOException
- */
- private static void writeF2(Map<String, Integer> frequencyDictionary2) throws IOException {
- File file = new File(FILE_NAME2);
- FileWriter writer = new FileWriter(file);
- int rnd;
- while (file.length() < 10000) {
- for (int i = 0; i < 1024; i++) {
- rnd = (int) (Math.random() * 100 + 1);
- if (rnd <= 1) {
- writer.append((char) 65); // вероятность 0.01
- merge(frequencyDictionary2, (char) 65 + "");
- } else if (rnd > 1 && rnd <= 20) {
- writer.append((char) 66); // вероятность 0.19
- merge(frequencyDictionary2, (char) 66 + "");
- } else if (rnd > 20 && rnd <= 30) {
- writer.append((char) 67); //вероятность 0.1
- merge(frequencyDictionary2, (char) 67 + "");
- } else if (rnd > 30) {
- writer.append((char) 68); // вероятноть 0.7
- merge(frequencyDictionary2, (char) 68 + "");
- }
- }
- writer.flush();
- }
- }
- public static void merge(Map<String, Integer> map, String symbol) {
- if (map.containsKey(symbol)) {
- int oldCount = map.get(symbol);
- map.put(symbol, ++oldCount);
- } else {
- map.put(symbol, 1);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement