数据结构-电文传输

该实验用Java语言实现了哈夫曼树的构建,通过对给定字符串中ASCII码为0-255的字符频率统计,构造哈夫曼编码,然后进行加密和解密操作。实验过程中遇到的问题在老师指导下得以解决,强调了上机实践在理论学习中的重要性。
摘要由CSDN通过智能技术生成

一、实验目的

1、掌握二叉树的特点和性质;

2、掌握哈夫曼树的构造算法;

3、掌握哈夫曼树编码的构造算法。

二、实验内容

编写一个实验程序,随机给定一个字符串,统计其中ASCLL码为0-255的字符出现的次数,构造出对应的赫夫曼编码,用其替换产生加密码(其他字符保持不变),再由加密码解密产生原字符串,并且利用相关数据进行测试。

三、实验要求

1、实验报告要求用Java语言实现,2或3人一组。

2、完成“数据结构项目情境实验报告”。

3、完成项目程序代码的编写,并能正确运行

四、开发环境及人员分工

集成开发环境(IDE)

              Eclipse   JAVA 

项目成员

分工

五、实现过程详细说明

1.随机给定一个字符串

2.统计其中ASCLL码为0-255的字符出现的次数,

3.构造出对应的赫夫曼编码,

4.用其替换产生加密码(其他字符保持不变),再由加密码解密产生原字符串,并且利用相关数据进行测试。

六、实验总结

这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师的指导下,终于游逆而解。上机实习一方面能使书本上的知识变活,起到深化理解和灵活掌握教学内容的目的;另一方面,上机实习是对学生软件设计的综合能力的训练,包括问题分析,总体结构设计,程序设计基本技能和技巧的训练。

七、代码实现(程序粘贴,运行结果截图)

                                                                                

package news;

import java.util.Collections;

import java.util.Comparator;

import java.util.HashMap;

import java.util.LinkedList;

import java.util.Map;

import org.junit.Test;

public class wgyz {



    private class TreeNode {

        public TreeNode(Character ch, int val, int freq, TreeNode left, TreeNode right) {

            this.ch = ch;

            this.val = val;

            this.freq = freq;

            this.left = left;

            this.right = right;

        }

        Character ch;

        int val;

        int freq;

        TreeNode left;

        TreeNode right;

    } @Test public void testEncode(){

        String s = "wgyz-3143-zhzhx-3060";

        System.out.println("编码前:"+s);

        Object[] encodeRes = encode(s);

        String encodeStr = (String)encodeRes[0];

        Map<Character,String> encodeMap = (Map<Character, String>)encodeRes[1];

        System.out.println("编码表:");

        for(Map.Entry<Character,String> e:encodeMap.entrySet()){

            System.out.println(e.getKey()+":"+e.getValue());   }

        System.out.println("编码后:"+encodeStr);

        String decodeStr = decode(encodeStr,encodeMap);

        System.out.println("解码后:"+decodeStr);   }

    public Object[] encode(String s){

        Object[]res= new Object[2];

        Map<Character,String> encodeMap = new HashMap<Character, String>();

        TreeNode tree = constructTree(s);

        findPath(tree, encodeMap, new StringBuilder());

        findPath(tree, encodeMap, new StringBuilder());

        StringBuilder sb = new StringBuilder();

        for(int i=0;i<s.length();i++){

            String tmp = encodeMap.get(s.charAt(i));

            sb.append(tmp);    }

        res[0]=sb.toString();

        res[1] = encodeMap;

        return res;  }

    private TreeNode constructTree(String s) {

        if (s == null || s.equals("")) {return null; }

        //计算每个字母的词频,放到Map中

        Map<Character, Integer> dataMap = new HashMap<Character, Integer>();

        for (int i = 0; i < s.length(); i++) {

            Character c = s.charAt(i);

            if (dataMap.containsKey(c)) {

                int count = dataMap.get(c);

                dataMap.put(c, count + 1);

            } else { dataMap.put(c, 1);  } }

        LinkedList<TreeNode> nodeList = new LinkedList<TreeNode>();

        for (Map.Entry<Character, Integer> entry : dataMap.entrySet()) {

            Character ch = entry.getKey();

            int freq = entry.getValue();

            int val = 0;

            TreeNode tmp = new TreeNode(ch,val,freq,null,null);

            nodeList.add(tmp);  }

        Collections.sort(nodeList, new Comparator<TreeNode>() {

            public int compare(TreeNode t1, TreeNode t2) {

                return t1.freq-t2.freq;  }  });

        //size==1,代表字符串只包含一种类型的字母

        if(nodeList.size()==1){

            TreeNode t = nodeList.get(0);

            return new TreeNode(null,0,nodeList.get(0).freq,t,null); }

        TreeNode root = null;

        while(nodeList.size()>0){

            TreeNode t1 = nodeList.removeFirst();

            TreeNode t2 = nodeList.removeFirst();

            //左子树的val赋值为0,右子树的val赋值为1

            t1.val = 0;

            t2.val = 1;

            if(nodeList.size()==0){

                root = new TreeNode(null,0,t1.freq+t2.freq,t1,t2);  }else {

                //此时代表还有可以合并的节点

                TreeNode tmp = new TreeNode(null,0,t1.freq+t2.freq,t1,t2);

                //t1、t2合并后,需要将得到的新节点加入到原链表中,继续与其他节点合并,

                //此时需要保证原链表的有序性,需要进行排序

                if(tmp.freq>nodeList.getLast().freq){

                    nodeList.addLast(tmp); }else { for(int i=0;i<nodeList.size();i++){int tmpFreq = tmp.freq;if(tmpFreq<= nodeList.get(i).freq){  nodeList.add(i,tmp); break;      }  }    }   } } return root; }//对已经建立好的二叉树进行遍历,得到每个字符的编码

    private void findPath(TreeNode root, Map<Character,String> res, StringBuilder path) {

        if (root.left == null && root.right == null) {

            path.append(root.val);

            res.put(root.ch,path.substring(1));

            path.deleteCharAt(path.length() - 1);

            return;} path.append(root.val);

        if (root.left != null) findPath(root.left, res, path);

        if (root.right != null) findPath(root.right, res, path);

        path.deleteCharAt(path.length() - 1); }

    public String decode(String encodeStr,Map<Character,String> encodeMap){

        StringBuilder decodeStr = new StringBuilder();

        while(encodeStr.length()>0){

            for(Map.Entry<Character,String> e: encodeMap.entrySet()){

                String charEncodeStr = e.getValue(); if(encodeStr.startsWith(charEncodeStr)){

                    decodeStr.append(e.getKey());

                    encodeStr = encodeStr.substring(charEncodeStr.length());

                    break; } } }return decodeStr.toString();}}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值