题目: 哈夫曼编码大全

描述:

关于哈夫曼树的建立,编码,解码。

输入

第一行输入数字N,代表总共有多少个字符以及权值

第二第三行分别是一行字符串,以及每个字符对应的权值

接下来输入一个数M,表示接下来有M行字符串,要求你对每个字符串进行编码

再输入一个数X,表示接下来有X行编码,要求你对每行编码进行解码

输出

第一行输出所有节点的权重

接下来输出N行,每行以 “a:001”的格式输出每个字符对应的编码

接着输出M行,对输入的字符串的编码结果

最后,输出X行的解码结果

输入样例

6
abcdef
50 10 5 5 20 10
2
abcdef
defabaabbc
2
011001100100110110101101100
1100011000110101100101100

输出样例

50 10 5 5 20 10 10 20 30 50 100
a:0
b:100
c:1100
d:1101
e:111
f:101
010011001101111101
11011111010100001001001100
accbdfadb

cacadacfb


思路:

        编码:主要就是避免前面相同的部分,思路就是如果前面的找到了,但是加上后面的一个0或者1之后就找不到对应的解码字母,所以前面就是构成一个字母。

                     循环递归,时间可能多了点。

        解码:我就是用了一个变量去标记他是1还是0,不然的话就是你要看他是在哪一边,从而判断是不是0还是1.

                    循环递归,时间可能还是多了点。

       组成表:就是不断的选择,可以看前面的一篇博文buildHuffmanTree

                     相关链接:http://blog.csdn.net/zjwsa/article/details/78930200


 注:时间比较长,但是这些都是最简单的理解方法。


代码如下:

package com.huffmanTree.Test;
import java.util.Scanner;

class Node {
	int spot_value;///表示左右,0还是1
	int data;      ///表示该点的权值
	int father;    ///表示该点的父亲
	char ch;      ///表示该点的名字字母
	String p;     ///表示该点的编码

	/// 构造方法
	public Node(int n) {
		spot_value = -1;
		data = n;
		father = -1;
		p = "";
	}

	public Node() {
		spot_value = -1;
		data = -1;
		father = -1;
		p = "";
	}
}

public class ManyHuffmanTree {
	public static Node data[];
	public static int x2;
	public static int x1;
	public static int n;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		 n = sc.nextInt();
		String k = sc.next();
		/// 结点定义
		data = new Node[n * 2];
		for (int i = 1; i < n * 2; i++)
			data[i] = new Node();
		/// 下标从1开始,方便记忆
		for (int i = 1; i <= n; i++) {
			data[i].data = sc.nextInt();
			data[i].ch = k.charAt(i - 1);
		}
		
		int min, max, t;
		for (int i = 1; i <= n - 1; i++) {
			/// 刚开始找两个没有父亲的作为最小最大的初始值
			min = max = t = 0;
			for (int j = 1; j <= n + i - 1; j++) {
				if (data[j].father != -1)
					continue;
				if (t == 0)
					max = j;
				else
					min = j;
				t = t + 1;
				if (t == 2)
					break;
			}
			/// 先判断是不是要交换一下位置
			if (data[min].data > data[max].data) {
				int k1 = min;
				min = max;
				max = k1;
			}
			/// 下面就是正确的寻找最小和第二小的
			for (int j = 1; j <= n + i - 1; j++) {
				if (data[j].father != -1 || j == min || j == max)
					continue;
				if (data[j].data < data[min].data) {
					if (data[min].data <=  data[max].data)
						max = min;
					min = j;
				} else if (data[max].data > data[j].data)
					max = j;
			}
			/// 现在就是开始赋予孩子和父亲
			data[min].father = n + i;
			data[max].father = n + i;
			data[n + i].data = data[max].data + data[min].data;
			
			if (data[max].data == data[min].data) {
				if (max < min) {
					data[max].spot_value = 0;
					data[min].spot_value = 1;
				} else {
					data[max].spot_value = 1;
					data[min].spot_value = 0;
				}
			} else {
				if (data[max].data > data[min].data) {
					data[max].spot_value = 1;
					data[min].spot_value = 0;
				} else {
					data[max].spot_value = 0;
					data[min].spot_value = 1;
				}
			}
		}
		
		for (int i = 1; i <= n * 2 - 1; i++)
			System.out.print(data[i].data + " ");
		System.out.println();

		for (int i = 1; i <= n; i++) {
			System.out.print(data[i].ch + ":");
			search1(i, i);
			System.out.println();
		}
		// 解码
		int number = sc.nextInt();
		for (int i = 0; i < number; i++) {
			String t1 = sc.next();
			for (int j = 0; j < t1.length(); j++)
			System.out.println(data[k.indexOf(t1.charAt(j))+1].p);
		}
		/// 读码
		 number = sc.nextInt();
		for (int i = 0; i < number; i++) {
			String o = sc.next();
			similation(o);
			System.out.println();
		}
	}

	private static void similation(String o) {
		String u = "";
		for (int i = 0; i < o.length();i++) {
			u += o.charAt(i);
			if (i + 1 == o.length()) {
				chase(u, "");
			} else {
				int q = i;
				while (true) {
					x1 = x2 = 0;
					String l = u+o.charAt(i+1);
					chase(u, l);
					if (x1 != 0 && x2 == 0) {
						System.out.print(data[x1].ch);
						u = "";
					   break;
					}
					q++;
					if(q==o.length())
						break;
					u+=o.charAt(q);
				}
				i = q;
			}
		}

	}

	private static void chase(String u, String string) {
	   if(string==""){
		   for(int k=1;k<=n;k++)
		   {
			   if(u.equals(data[k].p)){
				   System.out.print(data[k].ch);
				   return ;
			   }
		   }
	   }else{
		   for(int k=1;k<=n;k++)
		   {
			   if(x1==0 && u.equals(data[k].p))
				   x1 = k;
		
			   if(x2==0 && string.equals(data[k].p))
				   x2 = k;
		   }
	   }
	}

	private static void search1(int index, int k) {
		if (data[index].father == -1) {
			return;
		}
		search1(data[index].father, k);
		data[k].p += data[index].spot_value;
		System.out.print(data[index].spot_value);
	}
}



            
posted @ 2017-12-29 13:24  让你一生残梦  阅读(1692)  评论(0编辑  收藏  举报