赞
踩
4.1 哈夫曼编/译码器
4.1.1 项目简介
哈夫曼编/译码器问题:利用哈夫曼编码(加密)进行信息通讯可以大大提高信道利用率,缩短信息传输时间,降低传输成本,保证报文安全。这要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(解密)。设计要求如下:
一个完整的系统应具有以下功能:
(1)初始化 (Initialization):从终端读入n个字符,建立哈夫曼树;
(2)编码 (Coding):利用已建好的哈夫曼树,对字符进行编码,然后将正文编码结果存入文件codefile中;
(3)译码 (Decoding):利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入文件textfile中。
建议:
代码清单
MainJFrame
package ex4_Huffman; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * @Version 1.0 * @Author:刘昕 * @Date:2021/3/30 11:06 * @Software: IntelliJ IDEA * @Content: */ public class MainJFrame extends JFrame implements ActionListener { public static Label text; JPanel functionPanel, textPanel, loadPanel, encodePanel, decodePanel, plainTextPanel, encodeTextPanel, decodeTextPanel; static JTextArea plainText; static JTextArea encodeText; static JTextArea decodeText; JScrollPane plainTextScroll, encodeTextScroll, decodeTextScroll; JButton loadButton, encodeButton, decodeButton; JTextField path; JLabel pathLabel; //存储明文 static String plain_text = ""; public MainJFrame(){ super("哈夫曼编码/译码"); this.setLayout(new BorderLayout()); this.setSize(900, 600); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //添加功能面板 functionPanel = new BackgroundPanel(); functionPanel.setBorder(BorderFactory.createTitledBorder("功能区")); loadPanel = new JPanel(); encodePanel = new JPanel(); decodePanel = new JPanel(); loadButton = new JButton("加载"); loadButton.addActionListener(this); encodeButton = new JButton("编码"); encodeButton.addActionListener(this); decodeButton = new JButton("译码"); decodeButton.addActionListener(this); pathLabel = new JLabel("路径:"); path = new JTextField(26); this.getContentPane().add(BorderLayout.NORTH, functionPanel); functionPanel.add(loadPanel); functionPanel.add(encodePanel); functionPanel.add(decodePanel); loadPanel.add(pathLabel); loadPanel.add(path); loadPanel.add(loadButton); encodePanel.add(encodeButton); decodePanel.add(decodeButton); //添加文本面板 textPanel = new JPanel(new GridLayout(1,3)); textPanel.setBorder(BorderFactory.createTitledBorder("文本区")); textPanel.setBackground(Color.GRAY); this.getContentPane().add(BorderLayout.CENTER, textPanel); plainTextPanel = new BackgroundPanel(); plainTextPanel.setBorder(BorderFactory.createTitledBorder("明文")); textPanel.add(plainTextPanel); encodeTextPanel = new BackgroundPanel(); encodeTextPanel.setBorder(BorderFactory.createTitledBorder("编码")); textPanel.add(encodeTextPanel); decodeTextPanel = new BackgroundPanel(); decodeTextPanel.setBorder(BorderFactory.createTitledBorder("译文")); textPanel.add(decodeTextPanel); plainText = new JTextArea(57,29); plainText.setBackground(Color.pink); plainText.setLineWrap(true); plainText.setFont(new Font("楷体",Font.BOLD,16)); encodeText = new JTextArea(57,29); encodeText.setBackground(Color.pink); encodeText.setLineWrap(true); encodeText.setFont(new Font("楷体",Font.BOLD,16)); decodeText = new JTextArea(57,29); decodeText.setBackground(Color.pink); decodeText.setLineWrap(true); decodeText.setFont(new Font("楷体",Font.BOLD,16)); plainTextScroll = new JScrollPane(plainText); plainTextScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); encodeTextScroll = new JScrollPane(encodeText); encodeTextScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); decodeTextScroll = new JScrollPane(decodeText); decodeTextScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); plainTextPanel.add(plainTextScroll); encodeTextPanel.add(encodeTextScroll); decodeTextPanel.add(decodeTextScroll); this.setVisible(true); } @Override public void actionPerformed(ActionEvent e) { //加载明文按键 if (e.getSource() == loadButton){ String Path = path.getText(); ReadFile.readTextFile(Path); } //输出编码按键 else if (e.getSource() == encodeButton){ new Huffman(); Huffman.encodeFunc(); } //输出译码按键 else if (e.getSource() == decodeButton){ Huffman.decodeFunc(); } } public static void main(String[] args){ new MainJFrame(); } }
Node
package ex4_Huffman; /** * @Version 1.0 * @Author:刘昕 * @Date:2021/3/30 10:55 * @Software: IntelliJ IDEA * @Content: class Node */ public class Node { String ch; int num; Node leftChild = null; Node rightChild = null; public Node(){} public Node(String ch, int num) { this.ch = ch; this.num = num; } @Override public String toString() { return "Node{" + "ch='" + ch + '\'' + ", num=" + num + '}'; } public String getCh() { return ch; } public void setCh(String ch) { this.ch = ch; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Node getLeftChild() { return leftChild; } public void setLeftChild(Node leftChild) { this.leftChild = leftChild; } public Node getRightChild() { return rightChild; } public void setRightChild(Node rightChild) { this.rightChild = rightChild; } public int compareTo(Node o2){ return this.getNum() - o2.getNum(); } }
Huffman
package ex4_Huffman; import ex1_学生报考系统.Student; import java.util.*; /** * @Version 1.0 * @Author:刘昕 * @Date:2021/3/30 10:59 * @Software: IntelliJ IDEA * @Content: */ public class Huffman { //字符及出现频率放入哈希表中 HashMap<String, Integer> map = new HashMap<>(); //编码 static HashMap<String, String> encodeMap = new HashMap<>(); //译码 static HashMap<String, String> decodeMap = new HashMap<>(); //哈希表中的数据放入数组中, 方便排序建树 ArrayList<Node> array = new ArrayList<>(); static Node tree; public Huffman(){ //把字符放入到哈希表中, key代表字符, value是出现频率 for (int i = 0; i < MainJFrame.plain_text.length(); i++){ String ch = MainJFrame.plain_text.charAt(i) + ""; //这个字符在map中没有,放入map if (map.get(ch) == null){ map.put(ch, 1); } //这个字符在map中存在,value+1重新放入 else{ map.replace(ch, map.get(ch), map.get(ch)+1 ); } } //哈希表中的数据放入数组中 for (Map.Entry<String, Integer> t : map.entrySet()){ Node temp = new Node(t.getKey(), t.getValue()); array.add(temp); } //进行排序 sortFunc(); //n为叶子节点数目, n2为2度节点数目 int n = array.size(); int n2 = n - 1; //建立哈夫曼树 for (int j = 0; j < n2; j++){ Node t = new Node(null, array.get(0).getNum()+array.get(1).getNum()); t.leftChild = array.get(0); t.rightChild = array.get(1); array.add(t); array.remove(0); array.remove(0); sortFunc(); } tree = array.get(0); } public void sortFunc(){ Collections.sort(array, new Comparator<Node>() { @Override public int compare(Node o1, Node o2) { return o1.compareTo(o2); } }); } //编码函数 public static void encodeFunc(){ encodeFunc2(Huffman.tree, "", encodeMap, decodeMap); for (int i = 0; i < MainJFrame.plain_text.length(); i++){ MainJFrame.encodeText.append(encodeMap.get(MainJFrame.plain_text.charAt(i)+"")); } } public static void encodeFunc2(Node tree, String code, HashMap<String, String> encodeMap, HashMap<String, String> decodeMap){ if (tree.rightChild == null ){ //编码表 encodeMap.put(tree.ch, code); //译码表 decodeMap.put(code, tree.ch); } else{ encodeFunc2(tree.leftChild, code + "0", encodeMap, decodeMap); encodeFunc2(tree.rightChild, code + "1", encodeMap, decodeMap); } } //译码函数 public static void decodeFunc(){ String s_decodeFunc = MainJFrame.encodeText.getText(); int j = 0; for (int i = 0; i < s_decodeFunc.length(); ){ j++; String s_decodeFunc2 = s_decodeFunc.substring(i, j); if (decodeMap.get(s_decodeFunc2) != null){ MainJFrame.decodeText.append(decodeMap.get(s_decodeFunc2)); i = j; } } } }
BackGroundPanel
package ex4_Huffman; import java.awt.Graphics; import java.awt.Image; import java.awt.event.ActionEvent; import javax.swing.ImageIcon; import javax.swing.JPanel; /** * @Version 1.0 * @Author:刘昕 * @Date:2021/3/30 11:55 * @Software: IntelliJ IDEA * @Content: */ public class BackgroundPanel extends JPanel { ImageIcon icon; Image img; public BackgroundPanel() { // /img/HomeImg.jpg 是存放在你正在编写的项目的bin文件夹下的img文件夹下的一个图片 icon = new ImageIcon(getClass().getResource("./Imag/3.jpg")); img = icon.getImage(); } public void paintComponent(Graphics g) { super.paintComponent(g); //下面这行是为了背景图片可以跟随窗口自行调整大小,可以自己设置成固定大小 g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this); } }
ReadFile
package ex4_Huffman; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; /** * @Version 1.0 * @Author:刘昕 * @Date:2021/3/30 14:28 * @Software: IntelliJ IDEA * @Content: */ public class ReadFile { public static void readTextFile(String path){ String encoding = "utf-8"; try{ File file = new File(path); if (file.isFile() && file.exists()){ InputStreamReader read = new InputStreamReader(new FileInputStream(file),encoding); BufferedReader bufferedReader = new BufferedReader(read); String lineTxt = null; while((lineTxt = bufferedReader.readLine()) != null){ MainJFrame.plainText.append(lineTxt); MainJFrame.plain_text += lineTxt; } read.close(); } else{ System.out.println("文件不存在!"); } } catch(Exception e){ System.out.println("读取文件出错"); e.printStackTrace(); } } }
源代码链接:
链接:https://pan.baidu.com/s/166JJ1cdQ2fqWoYg_BqtVGA
提取码:Code
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。