当前位置: 首页 > article >正文

从0开始打造自己的压缩软件(仅文字适配)上——文本的压缩

一、理清步骤首先作为一个程序我们必然是要一个输入的可能是个文本也可能是其他的内容。那么这个输入输出不能是像过去一样在终端中输入所以这里要引入我们的io流——即为我们的输入和输出的具体办法。然后我们要开始对文件进行压缩那么这里根据的要是什么标准呢因为我们输入的文本不同所以我们的编码方式一定要统一才行呀这里我们把每个字符都利用哈夫曼树进行可以编码从而达到压缩的目的。最后我们要做到把这个翻译出来再进行编译并输出就行了。二、着手进行压缩的部分1.读取首先先写一个读入的函数即传统意义上的输入。这里用到io包中的BufferedReader这个类。publicStringBuilderfileDatanewStringBuilder();StringpathE:\\input.txt;FilefnewFile(path);BufferedReaderbrnull;try{brnewBufferedReader(newFileReader(f));Stringline;while((linebr.readLine())!null){fileData.append(line).append(\r\n);}}catch(Exceptione){thrownewRuntimeException(e);}为了避免文件为空这里可以适用try-catch方法对相应的点进行抓取异常。然后可以加上其他的输出语句如果你需要。在这之后可以很轻松地看出来我们已将一个文件中的全部内容以一个Bufferreader 的形式将文件中的全部数据以一个fileData的读取器给取出来了while循环这里我们是将所有的内容以名为line 的字符串形式读取出来了所有的内容并把他们不断地拼接到起来直到我们没有了内容为止。到那时这还不是我们想要的结果因为现在它还是一个对象我们要不断地取出其中的字符并统计他们出现的频率这样才能搞出想要的结果。我待会说明。哈希表介绍联想到前次的哈希表解释不太全面我重新说一下——这里仅介绍相应的功能特点如需要一些更全面的代码获取请看我上次的文章哈希表和其他的小内容它有一点很好的效果就是在每次使用后面对相同的key值时可以不断地更新后面的value部分使得其能够被不断地使用并覆盖前面的value内容。在这里我们可以很好地使用并适配使得其能够作为一个统计器。现在我们就可以很好地 利用这一特性对每个字符进行统计了。HashMapString,IntegerhmnewHashMap();for(inti0;ifileData.length();i){charcfileData.charAt(i);//查找当前map中的是否存在keyif(hm.containsKey(c)){hm.put(c,hm.get(c)1);}else{hm.put(c,1);}}看到了吗我们通过不断地更新相应的value值将每一个char key都赋予了对应的value值体现了其一一对应的相关关系。2.建树接下来我们可以通过哈夫曼树对每个字符建树。不用担心这个新出现的数据结构。哈夫曼树介绍哈夫曼树是这样的对于一个数列来说不断地去取其中最小的两个数在这之后不断地进行对前两个数进行运算并把运算后的值重新放到数列中进行排列而后周而复始不断循环这样我们便可以得到一个将全部的数都变为一个树的全部叶子节点的树。接下来如果有根节点我们便可以轻松地知道每一个叶子节点的值。再接下来若使每一个节点都与其他节点区分开来我们可以从根节点开始给每一个分支进行编码比如将左儿子编码为0将右儿子编码为1重复此步骤直到所有的叶子节点都能拥有一连串的代表自己的编码。回到我们的应用上来这就可以作为一个例子既然我们需要将频率最高的目标标注出来我们就可以使用这个方法将目标进行相应的编码和使用从而出现每一个字符都有一一对应的相关的编码以字符串的方式进行存储该树即为我们将文件翻译成一连串编码的快捷密码本。for循环的另一个写法不过呢我们要先明了:for循环不是千古不变的一种写法forint i0;in;i{};如果语句需要变得简化我们可以这样写:for(i:n){}二者等效。现在我们先建一个树吧别忘了要先写一个TreeNode 的类不然我们没有根。classTreeNode{publicintdata;publicStringcode;publicStringstr;publicTreeNodeleft;publicTreeNoderight;publicTreeNode(){}publicTreeNode(intdata){this.datadata;}publicTreeNode(Stringstr,intdata){this.datadata;this.strstr;}}这样我们就可以在刚才的环境下建上另一个树了。for(Map.EntryString,Integerentry:hm.entrySet()){TreeNodenodenewTreeNode(entry.getKey(),entry.getValue());nodeList.add(node);这里是能够让每个字符都有能让他对应的节点。现在节点和树都有了链接就行了。publicvoidinOrder(){TreeNodecurrroot;StackTreeNodestacknewStack();while(curr!null||!stack.isEmpty()){if(curr!null){stack.push(curr);currcurr.left;}else{TreeNodenodestack.pop();currnode.right;}}}现在每个字符都已经有但是我们仍然要把他们和自己的编码链接起来让每一个字符都有自己的编码。publicvoidorder(TreeNoderoot,Stringcode){if(rootnull)return;if(root.leftnullroot.rightnull){root.codecode;System.out.println(root.str:root.code);h.put(root.str,root.code);}order(root.left,code0);order(root.right,code1);}既然我们已经有了对应的编码现在就更为方便了。要做的不过是把它从01编码压缩进行加密这是要把每八个01字符转换成一个10进制数字相应的笔记本反而会一各个地记录相应的数字对应的字符这样你的文字便会被加密没有密码本是无法看见的。publicvoidchuli(){intn(8-(g.length()%8))%8;intt0;Integerb0;charc;StringfnewString();Stringend;// char zg.charAt(0);// System.out.println(z);System.out.println();for(inti0;in;i){gg0;}//把g补完try{FileOutputStreamfosnewFileOutputStream(E:\\a.txt);ObjectOutputStreamoosnewObjectOutputStream(fos);oos.writeObject(h);oos.flush();for(inti0;ig.length();i){cg.charAt(i);ff(c);t;if(t8){System.out.println(ff);endendf;bInteger.parseInt(f,2);System.out.println(b);t0;f;fos.write(b);fos.flush();}}System.out.println(end);}catch(Exceptione){thrownewRuntimeException(e);}}好了有人可能注意到这里的不够8位的地方我全用的是0补齐这个地方看一下有个印象就好。本篇代码我放在下面了。packageHOLIDAY;importcom.sun.source.tree.Tree;importjava.sql.SQLOutput;importjava.util.*;importjava.io.*;publicclassHfmTree{publicTreeNoderoot;publicStringBuilderfileDatanewStringBuilder();HashMapString,IntegerhmnewHashMap();HashMapString,StringhnewHashMap();ListTreeNodenodeListnewLinkedList();Stringg;publicvoidread(){// String path D:\\IdeaProjects\\Java01\\src\\K\\Begin.java;0StringpathE:\\input.txt;FilefnewFile(path);BufferedReaderbrnull;try{brnewBufferedReader(newFileReader(f));Stringline;while((linebr.readLine())!null){fileData.append(line).append(\r\n);}}catch(Exceptione){thrownewRuntimeException(e);}System.out.println( fileData fileData.toString());//统计字符频率for(inti0;ifileData.length();i){charcfileData.charAt(i);//查找当前map中的是否存在keyif(hm.containsKey(c)){hm.put(c,hm.get(c)1);}else{hm.put(c,1);}}for(Map.EntryString,Integerentry:hm.entrySet()){TreeNodenodenewTreeNode(entry.getKey(),entry.getValue());nodeList.add(node);}//忘了干啥的了这步}publicvoidsort(ListTreeNodenodeList){for(inti0;inodeList.size();i){for(intj0;jnodeList.size()-1;j){if(nodeList.get(j).datanodeList.get(j1).data){TreeNodetempnodeList.get(j);nodeList.set(j,nodeList.get(j1));nodeList.set(j1,temp);}}}}publicvoidcreateTree(ListTreeNodenodeList){while(nodeList.size()1){sort(nodeList);TreeNodeleftnodeList.remove(0);TreeNoderightnodeList.remove(0);TreeNodenodenewTreeNode(left.dataright.data);node.leftleft;node.rightright;nodeList.add(node);}rootnodeList.remove(0);}publicvoidinOrder(){TreeNodecurrroot;StackTreeNodestacknewStack();while(curr!null||!stack.isEmpty()){if(curr!null){stack.push(curr);currcurr.left;}else{TreeNodenodestack.pop();currnode.right;}}}publicvoidorder(TreeNoderoot,Stringcode){if(rootnull)return;if(root.leftnullroot.rightnull){root.codecode;System.out.println(root.str:root.code);h.put(root.str,root.code);}order(root.left,code0);order(root.right,code1);}publicvoidda(){for(inti0;ifileData.length();i){charcfileData.charAt(i);ggh.get(c);}System.out.print(g);}publicvoidchuli(){intn(8-(g.length()%8))%8;intt0;Integerb0;charc;StringfnewString();Stringend;// char zg.charAt(0);// System.out.println(z);System.out.println();for(inti0;in;i){gg0;}//把g补完try{FileOutputStreamfosnewFileOutputStream(E:\\a.txt);ObjectOutputStreamoosnewObjectOutputStream(fos);oos.writeObject(h);oos.flush();for(inti0;ig.length();i){cg.charAt(i);ff(c);t;if(t8){System.out.println(ff);endendf;bInteger.parseInt(f,2);System.out.println(b);t0;f;fos.write(b);fos.flush();}}System.out.println(end);}catch(Exceptione){thrownewRuntimeException(e);}}publicstaticvoidmain(String[]args){HfmTreehfmnewHfmTree();hfm.read();hfm.createTree(hfm.nodeList);hfm.inOrder();hfm.order(hfm.root,);hfm.da();hfm.chuli();}}classTreeNode{publicintdata;publicStringcode;publicStringstr;publicTreeNodeleft;publicTreeNoderight;publicTreeNode(){}publicTreeNode(intdata){this.datadata;}publicTreeNode(Stringstr,intdata){this.datadata;this.strstr;}}//flie input.string

相关文章:

从0开始打造自己的压缩软件(仅文字适配)上——文本的压缩

一、理清步骤 首先作为一个程序,我们必然是要一个输入的,可能是个文本,也可能是其他的内容。那么这个输入输出不能是像过去一样在终端中输入,所以这里要引入我们的io流——即为我们的输入和输出的具体办法。 然后,我们…...

if语句

含义if就是判断条件,满足就执行,不满足就跳过,相当于“如果……就……”代码基础格式:if 条件:满足条件才运行的代码(打完冒号之后要按回车键自动缩进,直接顶格写会报错,手动缩进不符…...

2026最好用的图片处理工具推荐:去水印 / 抠图 / 高清化实测对比

2026最好用的图片处理工具推荐:去水印 / 抠图 / 高清化实测对比 前言:一张图片毁掉一个项目?别让烂工具耽误你 2026年,AI图片处理技术早已不是三年前的水平。发丝级抠图、去水印无痕、超分辨率重建……这些功能听起来很美好&…...

Claude Code 接入 DeepSeek

安装 Claude Code DeepSeek 文档: 使用如下命令安装 Claude Code: npm install -g anthropic-ai/claude-code安装完成后,可以输入下面的命令检查是否安装成功。 claude --version购买 DeepSeek API 创建 Api Key 点击如下链接创建 DeepSeek API Ke…...

P15895 [TOPC 2025] One-Way Abyss 题解

P15895 [TOPC 2025] One-Way Abyss Link: https://www.luogu.com.cn/problem/P15895 题目描述 米蒂是一位勇敢的冒险家,正在探索一个名为“深渊”的神秘地下洞穴系统。深渊由 nnn 条垂直的竖井和 mmm 条水平的隧道组成。每条隧道恰好连接同一深度上的两条竖井。所…...

一文讲清楚规则、Skill、MCP

想象一下,你要开一家餐厅,并招聘了一位AI员工。这三样东西,就是你管理这位新员工的完整装备。1. 规则 —— 餐厅的“企业文化手册”• 这是什么:这是你给AI员工的第一份文件,一本总纲领、总章程。它不教具体怎么做菜&a…...

别再手动下载DLL了!用Windows自带工具SFC/SCANNOW一键修复kernel32.dll错误

别再手动下载DLL了!用Windows自带工具SFC/SCANNOW一键修复kernel32.dll错误当电脑屏幕上突然弹出"无法定位程序输入点kernel32.dll"的红色警告框时,大多数人的第一反应是打开浏览器搜索"如何下载kernel32.dll"。这个看似合理的操作背…...

告别.bash_profile:在macOS Ventura/Sonoma上为Maven配置环境变量的几种新方法(含Zsh教程)

macOS Ventura/Sonoma时代:Maven环境变量配置的现代实践指南如果你最近升级到了macOS Ventura或Sonoma,可能会发现那些教你修改.bash_profile来配置Maven环境变量的教程突然不灵了。这不是你的问题——而是macOS的Shell环境已经悄然进化。作为长期在macO…...

企业官网后台的工程化设计:内容建模、所见即所得与源码自主可控

企业官网后台的工程化设计:内容建模、所见即所得与源码自主可控 “网站做完我们自己能改吗?要不要技术?”——这个业务问题,在工程层面其实是问:这套 CMS 的内容模型、编辑体验、权限和可维护性设计得怎么样。 后台&qu…...

Win10桌面右键新建菜单丢了记事本?别慌,手把手教你用注册表找回来(附权限设置详解)

Win10右键新建菜单丢失记事本?三步精准修复与权限管理指南刚泡好的咖啡还在冒热气,你像往常一样在桌面右键点击"新建",却发现那个最常用的"文本文档"选项凭空消失了。这不是个例——微软官方社区数据显示,每月…...

Bi-LSTM vs CNN-BiLSTM:实战对比哪个模型更适合你的时间序列预测任务?

Bi-LSTM与CNN-BiLSTM实战抉择:时间序列预测的黄金选择法则当面对时间序列预测任务时,选择正确的模型架构往往能决定项目的成败。Bi-LSTM和CNN-BiLSTM作为两种主流的深度学习模型,各自在特定场景下展现出独特优势。本文将带您深入剖析这两种模…...

别再为立体匹配发愁了!手把手教你用Fusiello法搞定双目相机极线校正(附Python代码)

双目视觉实战:Fusiello极线校正算法详解与Python实现在计算机视觉领域,立体匹配是获取三维场景信息的关键步骤。但原始双目图像由于相机位置差异,导致匹配搜索空间复杂,计算效率低下。本文将深入解析Fusiello极线校正算法的数学原…...

避坑指南:在openEuler 22.03上配置vsftpd虚拟用户,解决gdbmtool替代db_load的认证问题

深度解析:在openEuler 22.03上配置vsftpd虚拟用户的最佳实践 最近在openEuler 22.03上配置vsftpd虚拟用户时,我发现了一个让不少从CentOS/RHEL迁移过来的管理员头疼的问题:传统的 db_load 方法在这里行不通了。经过一番探索和踩坑&#xff…...

MacBook新手福音:用Final Cut Pro 10.6.5搞定你的第一门视频课(附保姆级设置与导出指南)

MacBook新手福音:Final Cut Pro 10.6.5视频课制作全流程精解第一次打开Final Cut Pro时,那个布满陌生术语的界面是否让你望而却步?作为Mac用户专属的视频剪辑利器,它其实远比想象中友好。本文将带你用最直接的方式,从零…...

别再让Ubuntu卡成PPT!手把手教你用swapfile把交换空间从1G扩容到64G(附权限修复)

Ubuntu系统Swap空间扩容实战:从1G到64G的完整解决方案当你在Ubuntu上运行内存密集型任务时,是否遇到过系统突然变得异常缓慢,甚至完全卡死的情况?很多拥有大内存(如32GB或更高)的用户可能会惊讶地发现&…...

别再只认ldd了!盘点5种查看Linux程序动态库依赖的方法(含静态/交叉编译场景)

超越ldd:Linux二进制依赖分析的5种专业方法解析在Linux系统管理和开发中,遇到"不是动态可执行文件"的错误提示时,很多工程师的第一反应是困惑——明明是可执行文件,为什么ldd无法识别?这个问题背后隐藏着Lin…...

【程序源代码】答题微信小程序(含源码)

关键字:答题,小程序,OCR, 题目识别,题库,练习,错题集,微信小程序,Vue项目名称:答题微信小程序答题小程序是面向学生群体打造的轻量化在线答题学习平台,基于微…...

交通顶刊TR Part C 2026年6月论文导读(下)

一期刊简介Transportation Research Part C (TR-C): Emerging Technologies 是交通领域顶刊,由 Elsevier 出版,中科院与 JCR 均为 1 区,近年影响因子约8–9.6。该期刊以交通系统为核心,聚焦 AI、大数据、运筹学等新兴技术对交通规…...

AI应用开发岗面经

1、请先做一下自我介绍。2、你的毕设作品,从产品需求设计到后续开发全流程,都是你一个人独立完成的吗?3、你为什么会选择做这个毕设项目?4、你在做这个项目的过程中,遇到的比较大的挑战是什么?5、你为什么会…...

选型必看!国产RT-Thread才是商用量产最优解

做嵌入式项目选型,很多工程师总会纠结:Zephyr、FreeRTOS、uC/OS、RT-Thread到底怎么选?不少测评一味堆砌极限跑分数据,盲目吹捧海外系统的参数优势,却忽略了国内企业最看重的国产化合规、开发效率、落地量产、售后保障…...

Titanic数据集分析避坑指南:新手常犯的3个错误及如何修正

Titanic数据集分析避坑指南:新手常犯的3个错误及如何修正泰坦尼克号数据集是机器学习领域的"Hello World",但看似简单的数据背后藏着无数陷阱。许多初学者在Kaggle等平台提交分析时,常常陷入三个典型误区:用均值粗暴填充…...

VMware升级后Ubuntu 22.04虚拟机网卡‘消失’?别慌,这6个命令帮你一键找回(附排查思路)

VMware升级后Ubuntu 22.04虚拟机网卡异常修复指南当你满怀期待地将VMware Workstation从15版升级到17版,准备体验新功能时,突然发现原本运行良好的Ubuntu 22.04虚拟机无法联网了——ifconfig只显示lo回环接口,网络设置里空空如也。这种"…...

MacBook锁屏别慌!手把手教你用恢复模式+Apple ID重置开机密码(保姆级图文)

MacBook锁屏急救指南:3种安全解锁方案详解刚泡好的咖啡还在冒热气,手指悬在键盘上方却突然僵住——那个每天输入几十次的密码,此刻竟怎么也想不起来了。MacBook屏幕上冰冷的"密码错误"提示像一堵墙,将你与所有工作资料、…...

不止是搜索!Listary隐藏玩法大揭秘:网页传文件、快速启动器、资源管理器增强

Listary进阶指南:解锁Windows效率中枢的隐藏玩法双击Ctrl键调出搜索框——这可能是大多数Listary用户对这个工具的全部认知。但如果你只把它当作一个文件搜索工具,那就像用瑞士军刀只开瓶盖一样暴殄天物。经过三年深度使用和上百次工作流优化&#xff0c…...

别再乱装驱动了!Win10/Win11频繁蓝屏DPC_WATCHDOG_VIOLATION,用WinDBG揪出真凶(保姆级排查流程)

彻底解决Win10/Win11蓝屏噩梦:DPC_WATCHDOG_VIOLATION实战排查指南每次看到那个蓝色屏幕突然出现,心跳都会漏掉一拍——特别是当重要文件还没来得及保存的时候。DPC_WATCHDOG_VIOLATION(错误代码133)堪称Windows系统最令人头疼的蓝…...

别再只会用P值了!用Python的Scipy库实战t检验(附完整代码与结果解读)

用Python玩转t检验:从理论到代码的实战指南当你面对两组数据,想知道它们的均值是否存在显著差异时,t检验是最常用的统计工具之一。但很多数据分析师和机器学习实践者常常陷入"理论懂,代码不会写"的困境。本文将带你用Py…...

安卓高版本APP抓包实战:破解证书校验与NetworkSecurityConfig

1. 为什么高版本安卓APP抓包越来越像“拆弹”——从系统证书机制说起你有没有试过,把BurpSuite配好代理、雷电模拟器9开起来、APP一启动就报“网络连接异常”?或者更魔幻的:APP能打开,但所有接口请求在Burp里压根不出现&#xff0…...

Drupal YAML反序列化RCE漏洞CVE-2017-6920深度解析

1. 这不是“又一个RCE”,而是一次对Drupal架构信任边界的彻底重写2017年3月,Drupal官方发布安全通告,编号CVE-2017-6920,定级为Critical(严重),CVSS评分高达9.8。当时我正在给一家省级政务平台做…...

安卓反调试绕过实战:Frida分层Hook与动态修复指南

1. 为什么“绕过反调试”不是技术炫技,而是逆向分析的生存底线在安卓应用安全分析现场,我见过太多人卡在第一关:刚用adb shell连上设备,frida -U -f com.example.app --no-pause一敲下去,目标App闪退,Logca…...

基于PSO的多目标优化匿名化模型MO-OBAM:平衡隐私保护与数据效用的实战指南

1. 项目概述:当数据共享遇上隐私红线,我们如何破局?在数据驱动的时代,无论是医疗研究中的患者电子病历、金融风控中的信用记录,还是商业分析中的用户行为数据,其共享与分析都蕴含着巨大的价值。然而&#x…...