首页 > 编程语言 >哈弗曼编码与反编码的实现 java源代码

哈弗曼编码与反编码的实现 java源代码

时间:2023-10-07 16:32:31浏览次数:38  
标签:reset 编码 源代码 ok private table 弗曼


哈弗曼编码与反编码的实现  java源代码下载地址:

哈弗曼编码与反编码的实现  java源代码_file

哈弗曼编码与反编码的实现  java源代码_string_02

public class Huffman {
	public static void main(String[] args) {
	new	HaffmanFrame();
	
   }
}
//主界面类
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//主界面
public class HaffmanFrame extends JFrame implements ActionListener {
	
	private static final long serialVersionUID = 1808617924849665897L;
	private JButton  choice, ok, reset,recoding,re;//choice 文件选择,ok 确定 ,reset 重置,recoding 反编译
	private JLabel choiceJL,codingJL,recodingJL;//选择  编码 反编码 标签
	private JTextArea inputJTA,recodingJTA;
	private JScrollPane js1,js2,js3;
    private HaffmanJTable table ;
    private TotalChars tc = null;
    private HffmanCoding hfc = null;
	HaffmanFrame(){
		super("哈弗曼编码与反编码");
		newFrame();//界面的初始化
        formeValidate();
	}
	@Override 
	public void actionPerformed(ActionEvent e) {
		// TODO 事件的处理
        if(e.getSource() ==  choice) {
        	open();
        }
        else if(e.getSource() == ok) {
        	ok();
       }
        else if(e.getSource() == reset) {
        	reset();
        }
        else if(e.getSource() == recoding) {
        	if(tc != null )
        		{
        		JOptionPane.showMessageDialog(this, hfc.reCoding(recodingJTA.getText()), "反哈弗曼编码文本",
    					JOptionPane.DEFAULT_OPTION);
        		}
        }
        else if(e.getSource() == re) {
        	recodingJTA.setText(null);
        }
	}
	//重置
	private void reset() {
		inputJTA.setText("");
		recodingJTA.setText("");
		table.beginTable();
		table.repaint();
	}
//   确定
	private void ok() {
		table.beginTable();
		table.repaint();
	     tc = new TotalChars();
		int chars[][] = tc.getCharAddWeight(inputJTA.getText());
	     hfc = new HffmanCoding(chars);
		hfc.coding();//哈弗曼树
		String s[] = hfc.CreateHCode();//哈弗曼编码
		for (int i = 0; i < chars.length; i++) {
			
				if (chars[i][0]<= 32)
					table.setT(i, 0, "A" + String.valueOf(chars[i][0]));//以ascll码的形式在表格输出
				else
					table.setT(i, 0, String.valueOf((char) chars[i][0]));//以字符的形式在表格输出
				table.setT(i, 1, String.valueOf(chars[i][1]));
				table.setT(i, 2, s[i]);
		}
		recodingJTA.setText(hfc.show(inputJTA.getText()));
		table.repaint();
	}
//	打开
	private void open() {
		inputJTA.setText("");
		FileOpen fo = new FileOpen(this);
		fo.open();
		inputJTA.setText(fo.getText());
		fo = null;
	}
	
	//界面的初始化
	private void newFrame() {
		table = new HaffmanJTable();
		choice   = new JButton("选择文件");
		ok       = new JButton("确     定");
		reset    = new JButton("重     置");
		recoding = new JButton("反编码");
		re       = new JButton("重置反编码");
		
		choiceJL   = new JLabel("请选择文件或输入文本:");
		codingJL   = new JLabel("字符的哈弗曼编码:");
		recodingJL = new JLabel("文本的哈弗曼编码表示:");
        inputJTA     = new JTextArea(5,5);
        recodingJTA  = new JTextArea(5,5);
        recodingJTA.setLineWrap(true);
        js1 = new JScrollPane(inputJTA); 
        js2 = new JScrollPane(table.myTable()); 
        js3 = new JScrollPane(recodingJTA); 
        
        //设置位置
        choiceJL.setBounds(10, 10, 150, 30);
        js1.setBounds(160, 10, 320, 150);
        ok.setBounds(200, 170, 80, 30);
        reset.setBounds(350, 170, 80, 30);
        choice.setBounds(30,50,100,30);
        codingJL.setBounds(10, 210, 150, 30);
        js2.setBounds(160, 210, 320, 150);
        recodingJL.setBounds(10, 370, 150, 30);
        js3.setBounds(160, 370, 320, 150);
        recoding.setBounds(30, 410, 100, 30);
        re.setBounds(30, 450, 100, 30);
        
        this.setLayout(null);
        this.add(choiceJL);
        this.add(js1);
        this.add(ok);
        ok.addActionListener(this);
        this.add(reset);
        reset.addActionListener(this);
        this.add(choice);
        choice.addActionListener(this);
        this.add(re);
        re.addActionListener(this);
        this.add(codingJL);
        this.add(js2);
        this.add(recodingJL);   
        this.add(js3);
        this.add(recoding);
        recoding.addActionListener(this);
        
        Font f = new Font("宋体",Font.BOLD,15);//设置字体
        inputJTA.setFont(f);
        recodingJTA.setFont(f);
	}
	private void formeValidate() {
		Toolkit tk = getToolkit();//获得屏幕的宽和高
		Dimension dim = tk.getScreenSize(); 
	    this.setResizable(false);
		this.setBounds(dim.width/2-250, dim.height/2-280,500,570); 
        setVisible(true);
        validate();
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}
//表格类
import java.awt.Component;
import java.awt.Font;
import javax.swing.JTable;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class HaffmanJTable {
	private JTable table;
	private Object t[][] = new Object[100][3];//用来存放字符  次数   和哈弗曼编码
	private Object name[] = {"字符","次数","哈弗曼编码"};//用来存放表头
	public Component myTable() {
		// TODO Auto-generated method stub
		table    = new JTable(t,name);
		Font f = new Font("宋体",Font.BOLD,15);//设置字体
		table.setFont(f);
		setColumnSize(0,40);//设置第1列的大小
		setColumnSize(1,60);//设置第2列的大小
		setColumnSize(2,202);//设置第3列的大小
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);//AUTO_RESIZE_OFF 
                                                       // 不自动调整列的宽度;使用滚动条。
		                                               //table.setAutoResizeMode()当调整表的大小时,设置表的自动调整模式。
		return table;
	}
	public void setT(int i ,int j, String volue) {//设置表格的值
		this.t[i][j] = volue;
	}
	public void setColumnSize(int i, int width ) {
		TableColumnModel   cm   =   table.getColumnModel();     //表格的列模型
		TableColumn   column  = cm.getColumn(i);//得到第i个列对象   
		column.setPreferredWidth(width);//将此列的首选宽度设置为 preferredWidth。
		//如果 preferredWidth 超出最小或最大宽度,则将其调整为合适的界限值。 
	}
	public void repaint() {//重绘表格
		table.repaint();
	}
	public void beginTable()//重值表格
	{
		for (int i = 0; i < 100; i++) {
			for (int j = 0; j < 3; j++)
				setT(i, j, "");
		}
	}
}

//文件的打开
import java.awt.FileDialog;
import java.awt.event.*;
import java.io.*;
import java.io.File;
import java.io.FileReader;
public class FileOpen {
	private FileDialog filedialog_open;
	private String fileopen = null, filename = null;// 用于存放打开文件地址 和文件名
	private File file1; // 文件字节流对象
	private FileReader file_reader;//文件字符流对象
	private BufferedReader in;//文件行读取 写入对象
	private StringBuffer text = new StringBuffer();
	
	HaffmanFrame haffman= null;
	FileOpen(HaffmanFrame hf) {
		haffman = hf;
		filedialog_open = new FileDialog(haffman, "打开文件对话框", FileDialog.LOAD);
		// 打开文件对话框适配器
		filedialog_open.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				filedialog_open.setVisible(false);
			}
		});
	}
	public void open() {
		String s = ""; 
		filedialog_open.setVisible(true);
		fileopen = filedialog_open.getDirectory();// 返回文件对话框中显示的文件所属的目录
		filename = filedialog_open.getFile();// 返回当前文件对话框中显示的文件名的字符串表示
												// 如果不存在就返回NULL
		if (filename != null)// 判断打开的文件是否存在
		{
			try {
				file1 = new File(fileopen,filename );
				file_reader = new FileReader(file1);
	            in = new BufferedReader(file_reader);//每次读取一行
	            while ((s = in.readLine()) != null)
			    text.append(s + '/n');
			    in.close();
	            file_reader.close();
			} catch (IOException e2) {
				System.out.println("不能打开文件!");
			}
		}
	}
	//返回得到的文本字符串
	public String getText() {
		return new String(text);
	}
}

//统计字符类
public class TotalChars {
	private int charCount[] = new int[255];
	private char c[];//统计字符的个数
	private int  charAddWeight[][];//存放字符的ascll码值和字符的频率
	private int  total = 0;//存放需要编码字符的个数
	TotalChars(){
	for(int i = 0; i<255;i++)
		charCount[i] = 0;
	}
    //统计每个字符的出现的个数
	public void charToal(String s) {
		
		c = new char[s.length()];
		c = s.toCharArray();// 将字符串转化为字符数组
		for (int  i = 0; i < c.length; i++) {
			 int j = c[i];
			 charCount[j]++;  
		}
		for(int i = 0; i < 255 ; i++) {
			if (charCount[i] != 0) {
				total++;//统计字符的个数
			}
		}
	}
	
	//	返回字符的ascll码值和字符的频率
	public int[][] getCharAddWeight(String s){
		charToal(s);//统计每个字符的出现的个数
		charAddWeight = new  int[total][2];
		for(int i = 0,j=0; i < 255 ; i++) {
			
				if (charCount[i] != 0) {
					charAddWeight[j][0] = i;
					charAddWeight[j++][1] = charCount[i];
				}
		}	
		return charAddWeight;	
	}		
}

//哈弗曼编码的实现类
public class HffmanCoding {
	private int charsAndWeight[][];// [][0]是 字符,[][1]存放的是字符的权值(次数)
	private int hfmcoding[][];// 存放哈弗曼树
	private int i = 0;// 循环变量
	private String hcs[];
	public HffmanCoding(int[][] chars) {
		// TODO 构造方法
		charsAndWeight = new int[chars.length][2];
		charsAndWeight = chars;
		hfmcoding = new int[2 * chars.length - 1][4];// 为哈弗曼树分配空间
	}
	// 哈弗曼树的实现
	public void coding() {
		int n = charsAndWeight.length;
		if (n == 0)
			return;
		int m = 2 * n - 1;
		// 初始化哈弗曼树
		for (i = 0; i < n; i++) {
			hfmcoding[i][0] = charsAndWeight[i][1];// 初始化哈弗曼树的权值
			hfmcoding[i][1] = 0;// 初始化哈弗曼树的根节点
			hfmcoding[i][2] = 0;// 初始化哈弗曼树的左孩子
			hfmcoding[i][3] = 0;// 初始化哈弗曼树的右孩子
		}
		for (i = n; i < m; i++) {
			hfmcoding[i][0] = 0;// 初始化哈弗曼树的权值
			hfmcoding[i][1] = 0;// 初始化哈弗曼树的根节点
			hfmcoding[i][2] = 0;// 初始化哈弗曼树的左孩子
			hfmcoding[i][3] = 0;// 初始化哈弗曼树的右孩子
		}
		// 构建哈弗曼树
		for (i = n; i < m; i++) {
			int s1[] = select(i);// 在哈弗曼树中查找双亲为零的 weight最小的节点
			hfmcoding[s1[0]][1] = i;// 为哈弗曼树最小值付双亲
			hfmcoding[s1[1]][1] = i;
			hfmcoding[i][2] = s1[0];// 新节点的左孩子
			hfmcoding[i][3] = s1[1];// 新节点的右孩子
			hfmcoding[i][0] = hfmcoding[s1[0]][0] + hfmcoding[s1[1]][0];// 新节点的权值是左右孩子的权值之和
		}
	}
	// 查找双亲为零的 weight最小的节点
	private int[] select(int w) {
		// TODO Auto-generated method stub
		int s[] = { -1, -1 }, j = 0;// s1 最小权值且双亲为零的节点的序号 , i 是循环变量
		int min1 = 32767, min2 = 32767;
		for (j = 0; j < w; j++) {
			if (hfmcoding[j][1] == 0) {// 只在尚未构造二叉树的结点中查找(双亲为零的节点)
				if (hfmcoding[j][0] < min1) {
					min2 = min1;
					s[1] = s[0];
					min1 = hfmcoding[j][0];
					s[0] = j;
				} else if (hfmcoding[j][0] < min2) {
					min2 = hfmcoding[j][0];
					s[1] = j;
				}
			}
		}
		return s;
	}
	public String[] CreateHCode() {// 根据哈夫曼树求哈夫曼编码
		int n = charsAndWeight.length;
		int i, f, c;
		String hcodeString = "";
		hcs = new String[n];
		for (i = 0; i < n; i++) {// 根据哈夫曼树求哈夫曼编码
			c = i;
			hcodeString = "";
			f = hfmcoding[i][1]; // f 哈弗曼树的根节点
			while (f != 0) {// 循序直到树根结点
				if (hfmcoding[f][2] == c) {// 处理左孩子结点
					hcodeString += "0";
				} else {
					hcodeString += "1";
				}
				c = f;
				f = hfmcoding[f][1];
			}
			hcs[i] = new String(new StringBuffer(hcodeString).reverse());
		}
		return hcs;
	}
	public String show(String s) {// 对字符串显示编码
		String textString = "";
		char c[];
		int k = -1;
		c = new char[s.length()];
		c = s.toCharArray();// 将字符串转化为字符数组
		for (int i = 0; i < c.length; i++) {
			k = c[i];
			for (int j = 0; j < charsAndWeight.length; j++)
				if (k == charsAndWeight[j][0])
					textString += hcs[j];
		}
		return textString;
	}
	// 哈弗曼编码反编译
	public String reCoding(String s) {
		String text = "";// 存放反编译后的字符
		int k = 0, m = hfmcoding.length - 1;// 从根节点开始查询
		char c[];
		c = new char[s.length()];
		c = s.toCharArray();
		k = m;
		for (int i = 0; i < c.length; i++) {
			if (c[i] == '0') {
				k = hfmcoding[k][2];// k的值为根节点左孩子的序号
				if (hfmcoding[k][2] == 0 && hfmcoding[k][3] == 0)// 判断是不是叶子节点,条件(左右孩子都为零)
				{
					text += (char) charsAndWeight[k][0];
					k = m;
				}
			}
			if (c[i] == '1') {
				k = hfmcoding[k][3];// k的值为根节点右孩子的序号
				if (hfmcoding[k][2] == 0 && hfmcoding[k][3] == 0)// 判断是不是叶子节点,条件(左右孩子都为零)
				{
					text += (char) charsAndWeight[k][0];
					k = m;
				}
			}
		}
		return text;
	}
}

标签:reset,编码,源代码,ok,private,table,弗曼
From: https://blog.51cto.com/aimilin/7739328

相关文章

  • FreeSWITCH添加h264编码及pcap视频提取
    操作系统:CentOS7.6_x64、Windows10_x64FreeSWITCH版本:1.10.9Python版本:3.9.2一、启用h264相关模块这里以mod_openh264为例进行演示。1、安装open_h264库获取open_h264源码:gitclonehttps://github.com/cisco/openh264.git若下载过慢,可从如下渠道获取:关注微信......
  • app直播源代码,JavaWeb如何设置定时任务
    app直播源代码,JavaWeb如何设置定时任务1.在xml文件中添加监听器 <?xmlversion="1.0"encoding="UTF-8"?><web-appversion="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"......
  • 关于当下ChatGPT在软件工程编码过程反思
        背景    首先声明笔者是软件开发多年经历,对于ChatGPT过程中一些观察,仅代表个人观点。对于才工作的新人,没有更多软件开发与编码经验,可能ChatGPT帮助更大。当下ChatGPT在软件工程编码过程反思:    风险一: ChatGPT当下对于整个软件工程优化与改进所有源代码效......
  • 【论文2】自编码器为何Work?
     在研究stylelatentspace的概念时,我得到了对自编码器为何Work的解释:因为模型需要重建压缩数据,所以它必须学会存储所有相关信息并忽略噪声。这就是数据压缩的价值——它允许我们摆脱任何无关的信息,只关注最重要的特征。 ......
  • '''实验1 只有温度和时间 每个物料的初始温度和初始时间不一样 无分类变量需转为读热
    '''目标:拟合物料冷却规律分类变量:物料规格,冷却方式连续变量:温度,时间其他因素:车间温度现实因素:初始温度,初始时间需求因素:目标温度的时间,目标温度的时长(时间-初始时间),当前时间的温度不加入分类变量则为单个线性模型''''''实验1只有温度和时间每个物料的初始温......
  • Symchk.exe是微软提供的一个命令行工具,用于下载符号文件以帮助调试问题。符号文件包含
    Symchk.exe是微软提供的一个命令行工具,用于下载符号文件以帮助调试问题。符号文件包含用于将二进制文件映射回源代码的关键信息,可帮助开发人员在调试期间确定问题的根本原因。使用Symchk.exe,您可以指定要下载符号文件的二进制文件,该工具会查找相关的PDB文件并将其下载到本地计算......
  • 【十分钟一个知识点】数据、信息、编码
    数据数据是对客观事物的符号表示信息没有统一的定义,但是我们日常生活中所认为的信息都只是信息的载体特征:载体依附性:信息无法独立存在,依附于载体时效性:信息反映事物某一时间的状态、内容共享性:信息可以共享,同一种信息可以同时被不同的接收者获取可加工处理性、真伪性:信息......
  • 哈夫曼编码及例程
    哈夫曼编码是一种常见的无损压缩算法,通过根据字符出现的频率构建一个最优编码树,将频率较高的字符用较短的编码表示,从而实现数据的压缩。下面是一个简单的例程来演示如何使用哈夫曼编码进行文本数据的压缩和解压缩。压缩过程:统计输入文本中每个字符的出现频率。根据字符频率构建哈夫......
  • ​​pandas.get_dummies()​​ 是一个用于执行独热编码(One-Hot Encoding)的 pandas 函
    pandas.get_dummies()是一个用于执行独热编码(One-HotEncoding)的pandas函数。它用于将分类(或离散)特征转换为模型可以处理的二进制格式,以便更好地在机器学习算法中使用。独热编码将每个不同的类别值转换为一个新的二进制特征列,其中每个列代表一个类别,并且只有一个值为1,其余为0......
  • golang编码规范
     目录[-]golang编码规范gofmt注释命名控制结构函数(必须)错误处理panicimport缩写参数传递接受者 golang编码规范注:此文档参考官方指南EffectiveGolang和GolangCodeReviewComments进行整理,力图与官方及社区编码风格保持一致。gofmt大部分的格式问题可以通过gofmt解决,gofmt自动......