建樹,造樹,編碼,解碼java
0.1,0.1,0.1,0.1,0.1,0.1,0.2,0.2
i like you //文檔
字符 | 頻率 |
---|---|
i | 0.2 |
l | 0.1 |
k | 0.1 |
e | 0.1 |
y | 0.1 |
o | 0.1 |
u | 0.1 |
空格 | 0.2 |
從根向下一次讀取0或者1,進行編碼,編碼結果以下表git
字符 | 編碼 |
---|---|
i | 111 |
l | 010 |
k | 011 |
e | 000 |
y | 001 |
o | 100 |
u | 101 |
空格 | 110 |
for many young people they dont have the habit to save money because they think they are young and should enjoy the life quickly so there is no need to save money but saving part of the income can better help us to deal with emergent situations though it is hard to store income index zero we still can figure out some ways
//讀取文檔中的英文文檔 String[] a = new String[800]; try (FileReader reader = new FileReader("英文文檔"); BufferedReader br = new BufferedReader(reader) ) { int b =0; for (int i =0;i<800;i++){ a[b]=br.readLine(); b++; } } catch (IOException e) { e.printStackTrace(); } String[] b = a[0].split(""); // System.out.println(Arrays.toString(b)); //開始構造哈夫曼樹 Objects Za= new Objects("a",an); Objects Zb = new Objects("b",bn); Objects Zc = new Objects("c",cn); Objects Zd = new Objects("d",dn); Objects Ze = new Objects("e",en); Objects Zf = new Objects("f",fn); Objects Zg = new Objects("g",gn); Objects Zh = new Objects("h",hn); Objects Zi = new Objects("i",in); Objects Zj = new Objects("j",jn); Objects Zk = new Objects("k",kn); Objects Zl = new Objects("l",ln); Objects Zm = new Objects("m",mn); Objects Zn = new Objects("n",nn); Objects Zo = new Objects("o",on); Objects Zp = new Objects("p",pn); Objects Zq = new Objects("q",qn); Objects Zr = new Objects("r",rn); Objects Zs = new Objects("s",sn); Objects Zt = new Objects("t",tn); Objects Zu = new Objects("u",un); Objects Zv = new Objects("v",vn); Objects Zw = new Objects("w",wn); Objects Zx = new Objects("x",xn); Objects Zy = new Objects("y",yn); Objects Zz = new Objects("z",zn); Objects Zkongge = new Objects(" ",zkongge); System.out.println("各個字符的機率統計爲:"); Objects[] temp = new Objects[]{Za,Zb,Zc,Zd,Ze,Zf,Zg,Zh,Zi,Zj,Zk,Zl,Zm,Zn,Zo,Zp,Zq,Zr,Zs,Zt,Zu,Zv,Zw,Zx,Zy,Zz,Zkongge}; for (int i =0;i<temp.length;i++){ System.out.println(temp[i].getName()+"的機率爲"+temp[i].getWeight()/323); }
名字
,權重
,編碼
,還有他的左孩子
,右孩子
。package 哈夫曼樹編碼實驗; public class Objects implements Comparable<Objects> { private String name; private double weight; private String date; private Objects left; private Objects right; public Objects(String Name , double Weight){ name=Name; weight=Weight; date=""; } public String getName() { return name; } public double getWeight() { return weight; } public Objects getLeft() { return left; } public Objects getRight() { return right; } public void setLeft(Objects left) { this.left = left; } public void setRight(Objects right) { this.right = right; } public void setName(String name) { this.name = name; } public void setWeight(double weight) { this.weight = weight; } @Override public String toString() { return "Objects{" + "name='" + name + '\'' + ", weight=" + weight + ", 編碼爲='" + date + '\'' + '}'+"\n"; } @Override public int compareTo(Objects o) { if (weight>=o.weight){ return 1; } else { return -1; //規定發現權重相等向後放; } } public void setDate(String date) { this.date = date; } public String getDate() { return date; } }
List tempp = new ArrayList(); for (int i =0;i<temp.length;i++){ tempp.add(temp[i]); } Collections.sort(tempp); //將咱們的Objects類中的每個字符放進鏈表進行排序 while (tempp.size() > 1) { //直到咱們鏈表只剩下一個元素,也就是咱們的根結點的時候跳出循環 Collections.sort(tempp); //排序 Objects left = (Objects) tempp.get(0); //獲得第一個元素,做爲左孩子 left.setDate( "0"); //初始化左孩子的編碼爲0 Objects right = (Objects) tempp.get(1); //獲得第二個元素,做爲右孩子 right.setDate( "1"); //初始化有孩子的編碼爲1 Objects parent = new Objects(left.getName()+right.getName(), left.getWeight() + right.getWeight()); //構造父結點 parent.setLeft(left); //設置左結點 parent.setRight(right); //設置右結點 tempp.remove(left); //刪除左結點 tempp.remove(right); //刪除右結點 tempp.add(parent); //將父結點添加進入鏈表 }
//開始進行哈夫曼編碼 Objects root = (Objects) tempp.get(0); //咱們經過一個root保存爲根結點 System.out.println( ); //咱們利用先序遍歷,遍歷到每個結點,由於這樣能夠保證都從根結點開始遍歷 List list = new ArrayList(); Queue queue = new ArrayDeque(); queue.offer(root); while (!queue.isEmpty()){ list.add(queue.peek()); Objects temp1 = (Objects) queue.poll(); if(temp1.getLeft() != null) { queue.offer(temp1.getLeft()); temp1.getLeft().setDate(temp1.getDate()+"0"); //判斷假如爲左結點,就基於結點自己的編碼加上0 } if(temp1.getLeft() != null) { queue.offer(temp1.getRight()); temp1.getRight().setDate(temp1.getDate()+"1"); //判斷假如爲右結點,就基於結點自己的編碼加上1 } }
//進行加密 String result = ""; //定義了一個字符串,用來保存加密後的文檔 for (int i =0 ;i<b.length;i++){ for (int j=0;j<temp.length;j++){ if (b[i].equals(temp[j].getName())){ result+=temp[j].getDate(); //由於如今咱們以前保存Objects的數組中的每個字符已經有各自的編碼,因此咱們用咱們以前保存文檔的數組b進行對於,假如找到相對應的,就將編碼賦給result,進行累加,重複過程 break; } } } System.out.println("加密後"); System.out.println(result); File file = new File("加密後文檔"); FileWriter fileWritter = null; try { fileWritter = new FileWriter(file.getName(),true); } catch (IOException e) { e.printStackTrace(); } try { fileWritter.write(result); } catch (IOException e) { e.printStackTrace(); } try { fileWritter.close(); } catch (IOException e) { e.printStackTrace(); }
//解密,讀取須要解密的文檔 try (FileReader reader = new FileReader("加密後文檔"); BufferedReader br = new BufferedReader(reader) ) { int e =0; for (int i =0;i<800;i++){ a[e]=br.readLine(); e++; } } catch (IOException e) { e.printStackTrace(); } String duqu=a[0]; String jiemi=""; //保存解密後的文檔 String temp2=""; // 做爲一個臨時的字符串,一個一個進行獲取密文,當進行匹配成功了之後,變爲空,以下 for (int i =0;i<duqu.length();i++){ temp2+=duqu.charAt(i); for (int j = 0;j<temp.length;j++){ //這裏解密的思路就是咱們從加密的文檔中一個一個字符進行獲取,而後與咱們的以前建好的Objects數組中的元素的編碼 if (temp2.equals(temp[j].getDate())){ //進行獲取,而後獲取成功之後將其賦給jiemi,而後清空temp2; jiemi+=temp[j].getName(); temp2=""; } } } System.out.println("解密後"); System.out.println(jiemi); //將解密後的文本寫入文件 File file1 = new File("解密後文檔"); FileWriter fileWritter1 = null; try { fileWritter1 = new FileWriter(file1.getName(),true); } catch (IOException e) { e.printStackTrace(); } try { fileWritter1.write(jiemi); } catch (IOException e) { e.printStackTrace(); } try { fileWritter1.close(); } catch (IOException e) { e.printStackTrace(); }