当前位置:   article > 正文

哈夫曼编码(Java图形界面实现)_哈夫曼编码加上页面

哈夫曼编码加上页面
                                      4.1 哈夫曼编/译码器
  • 1

4.1.1 项目简介
哈夫曼编/译码器问题:利用哈夫曼编码(加密)进行信息通讯可以大大提高信道利用率,缩短信息传输时间,降低传输成本,保证报文安全。这要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(解密)。设计要求如下:
一个完整的系统应具有以下功能:
(1)初始化 (Initialization):从终端读入n个字符,建立哈夫曼树;
(2)编码 (Coding):利用已建好的哈夫曼树,对字符进行编码,然后将正文编码结果存入文件codefile中;
(3)译码 (Decoding):利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入文件textfile中。

建议:

  1. 将本次实验与《计算机网络》或者《计算机组成原理》中的通讯协议相结合,对报文进行加密\解密。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码清单
在这里插入图片描述
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();
    }
}

  • 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
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122

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();
    }
}

  • 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

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;
            }
        }
    }
}

  • 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

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);
    }

}

  • 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

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();
        }
    }
}
  • 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

源代码链接:
链接:https://pan.baidu.com/s/166JJ1cdQ2fqWoYg_BqtVGA
提取码:Code

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/859268
推荐阅读
相关标签
  

闽ICP备14008679号