1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| package top.binweber.shannon;
import android.util.Log;
import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.TreeMap;
public class FanoEncode { private static Map<Character,Integer> cLengthMap; private static Map<Character, String> codonMap; private static List<Map.Entry<Character, Double>> probArrayList; private static double aCLength;
public FanoEncode(Map<Character,Double> probMap) { aCLength = 0.0; cLengthMap = new TreeMap<>(); codonMap = new TreeMap<>();
probArrayList = new ArrayList<>(probMap.entrySet()); Collections.sort(probArrayList,new Comparator<Map.Entry<Character,Double>>() {
public int compare(Map.Entry<Character,Double> o1, Map.Entry<Character,Double> o2) { return o2.getValue().compareTo(o1.getValue()); } });
}
public Map<Character, String> toFano() { double[] pros = new double[probArrayList.size()];
int i = 0; for(Map.Entry<Character,Double> entry:probArrayList) { pros[i] = entry.getValue(); i++; }
String[] codon = getGroup(pros, 0, pros.length - 1);
int j = 0; for(Map.Entry<Character,Double> entry:probArrayList) { codonMap.put(entry.getKey(), codon[j]); cLengthMap.put(entry.getKey(), codon[j].length()); aCLength += pros[j] * codon[j].length(); j++; }
return codonMap; }
private String[] getGroup(double[] pros, int i, int j) { int middle = 0; String[] codens = new String[pros.length];
for (int k = 0; k < pros.length; k++) { codens[k] = ""; }
if(i < j) { double sum = 2; for(int k = i; k <= j; k++) { if(Math.abs(sumGroup(pros,i,k) - sumGroup(pros, k+1, j)) < sum) { sum = Math.abs(sumGroup(pros, i, k) - sumGroup(pros, k+1, j)); middle = k; } }
String[] codens_1 = getGroup(pros, i, middle); String[] codens_2 = getGroup(pros, middle+1, j);
for(int k = i; k <= middle; k++) { codens[k] = "0" + codens_1[k]; }
for(int k = middle + 1; k <= j ; k++) { codens[k] = "1" + codens_2[k]; } }
return codens; }
private double sumGroup(double[] pros,int i, int j) { double sum = 0.0;
for(int k = i; k <= j; k++) { sum += pros[k]; }
return sum; }
public Map<Character, Integer> getCLengthMap() { return cLengthMap; }
public List<Map.Entry<Character, Double>> getProbArrayList() { return probArrayList; }
public double getACLength() { BigDecimal bg = new BigDecimal(aCLength); aCLength = bg.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue(); return aCLength; }
}
|