我得到了哈夫曼编码后的原文章的01字符串的ASCII码文件,但是因为是这些0和1字符,所以比照原先的文章就更大了(这就没意义了)。我听老师说可以用一些方法将这个串变为二进制文件,这样就可以缩小了。
不过我不会- -,上网找了一些貌似没有说这个的。有哪位大神能够帮助我一下,提供一些可行的方法并且给出代码就最好了。方法和代码要可以压缩成二进制文件并且可以真的从那个二进制文件中读出01字串。
在这里谢谢大家了!
C++
// 你没说什么语言!如果需要其它的话,我再翻译一下!
// 没什么效率,但是满足需求了
import java.io.*;
public class Z {
public static void main(String[] args) throws Exception {
//System.out.println(decode(encode("00001000")));
//System.out.println(decode(encode("11111000")));
writeHuffman("011");
System.out.println(read()Huffman());
}
// 每次传进去的字符串都是8个字符长度,刚好能够表示一个byte
public static byte encode(String s) {
int a = 0;
for ( int i = 0; i < 8; i++) {
char ch = s.charAt(i);
a = a << 1;
if (ch == '1') {
a = a | 0x1;
}
}
return (byte)a;
}
// 上一步的逆操作
public static String decode(byte b) {
StringBuilder sb = new StringBuilder();
for ( int i = 0; i < 8; i++) {
sb.append((b & (0x1 << (7 - i))) > 0 ? '1' : '0');
}
return sb.toString();
}
// 再写一下文件操作
// 假设你已经得到了通过huffman树编码的字符串,那么就这样写写入文件
public static void writeHuffman(String s) throws Exception {
// 因为huffman编码字符串不总是8个字符的倍数,那么我们不足8时补0,并记录我们到底补了几个。
// 我们把补位数放在文件的第一个字节
int z = 8 - s.length() % 8;
if (z == 8) {
z = 0;
}
byte[] buffer = new byte[1024];
buffer[0] = (byte)z;
int pos = 1, nBytes = (int)(Math.ceil(s.length()/((double)8)));
File f = new File("test.huffman");
FileOutputStream os = new FileOutputStream(f);
for ( int i = 0; i < nBytes; i++) {
String ss;
if (s.length() >= (i + 1) * 8) {
ss = s.substring(i * 8, (i + 1) * 8);
} else {
ss = s.substring(i * 8);
while (ss.length() < 8) {
ss = new StringBuilder(ss).append('0').toString();
}
}
buffer[pos] = encode(ss);
pos++;
if (pos == 1024) {
os.write(buffer);
pos = 0;
}
}
if (pos > 0) {
os.write(buffer, 0, pos);
}
os.close();
}
// 我们把压缩过的文本放在test.huffman里面
public static String readHuffman() throws Exception {
File f = new File("test.huffman");
FileInputStream fs = new FileInputStream(f);
byte[] buffer = new byte[1024];
int len = 0;
StringBuilder sb = new StringBuilder();
byte z = (byte)fs.read();
while ((len = fs.read(buffer)) != -1) {
for ( int i = 0; i < len; i++) {
sb.append(decode(buffer[i]));
}
}
fs.close();
return sb.substring(0, sb.length() - z);
}
}
#include <stdio.h>
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
unsigned char encode(const char *s) {
int a = 0;
for ( int i = 0; i < 8; i++) {
if (s[i] == '1') {
a = a | (0x1 << (7 - i));
}
}
return (unsigned char)a;
}
void decode(unsigned char a, char *buf) {
for ( int i = 0; i < 8; i++) {
buf[i] = (((a >> (7 - i)) & 0x1) != 0) ? '1' : '0';
}
}
void writeHuffman(const string& s) {
unsigned char z = 8 - s.length() % 8;
if (z == 8) {
z = 0;
}
unsigned char buffer[1024];
buffer[0] = z;
int pos = 1, nBytes = (int)(ceil(s.length() / ((double)8)));
const char* ps = s.c_str();
FILE *fp = fopen("test.huffman", "wb");
char extended[8];
for ( int i = 0; i < nBytes; i++) {
const char *p;
if (s.length() >= (i + 1) * 8) {
p = ps + i * 8;
}
else {
char *pp = extended;
for ( int j = i * 8; j < s.length(); j++) {
*pp = s[j];
pp++;
}
for (int j = 0; j < z; j++) {
*pp = '0';
pp++;
}
p = extended;
}
buffer[pos] = encode(p);
pos++;
if (pos == 1024) {
fwrite(buffer, sizeof(unsigned char), 1024, fp);
pos = 0;
}
}
if (pos > 0) {
fwrite(buffer, sizeof(unsigned char), pos, fp);
}
fclose(fp);
}
string& readHuffman() {
FILE *fp = fopen("test.huffman", "rb");
fseek(fp, 0L, SEEK_END);
size_t fileSize = ftell(fp);
rewind(fp);
unsigned char buffer[1024];
fread(buffer, sizeof(unsigned char), 1, fp);
unsigned char z = buffer[0];
size_t stringSize = (fileSize - 1) * 8;
char *ptr = new char[stringSize + 1];
char *optr = ptr;
size_t len;
while ((len = fread(buffer, sizeof(unsigned char), 1024, fp)) != 0) {
for ( int i = 0; i < len; i++) {
decode(buffer[i], ptr);
ptr = ptr + 8;
}
}
fclose(fp);
ptr = ptr - z;
*ptr = '\0';
string* str = new string(optr);
delete []optr;
return *str;
}
int main(void)
{
writeHuffman("00010");
cout << readHuffman() << endl;
getchar();
return 0;
}
// 没什么效率,但是满足需求了
import java.io.*;
public class Z {
public static void main(String[] args) throws Exception {
//System.out.println(decode(encode("00001000")));
//System.out.println(decode(encode("11111000")));
writeHuffman("011");
System.out.println(read()Huffman());
}
// 每次传进去的字符串都是8个字符长度,刚好能够表示一个byte
public static byte encode(String s) {
int a = 0;
for ( int i = 0; i < 8; i++) {
char ch = s.charAt(i);
a = a << 1;
if (ch == '1') {
a = a | 0x1;
}
}
return (byte)a;
}
// 上一步的逆操作
public static String decode(byte b) {
StringBuilder sb = new StringBuilder();
for ( int i = 0; i < 8; i++) {
sb.append((b & (0x1 << (7 - i))) > 0 ? '1' : '0');
}
return sb.toString();
}
// 再写一下文件操作
// 假设你已经得到了通过huffman树编码的字符串,那么就这样写写入文件
public static void writeHuffman(String s) throws Exception {
// 因为huffman编码字符串不总是8个字符的倍数,那么我们不足8时补0,并记录我们到底补了几个。
// 我们把补位数放在文件的第一个字节
int z = 8 - s.length() % 8;
if (z == 8) {
z = 0;
}
byte[] buffer = new byte[1024];
buffer[0] = (byte)z;
int pos = 1, nBytes = (int)(Math.ceil(s.length()/((double)8)));
File f = new File("test.huffman");
FileOutputStream os = new FileOutputStream(f);
for ( int i = 0; i < nBytes; i++) {
String ss;
if (s.length() >= (i + 1) * 8) {
ss = s.substring(i * 8, (i + 1) * 8);
} else {
ss = s.substring(i * 8);
while (ss.length() < 8) {
ss = new StringBuilder(ss).append('0').toString();
}
}
buffer[pos] = encode(ss);
pos++;
if (pos == 1024) {
os.write(buffer);
pos = 0;
}
}
if (pos > 0) {
os.write(buffer, 0, pos);
}
os.close();
}
// 我们把压缩过的文本放在test.huffman里面
public static String readHuffman() throws Exception {
File f = new File("test.huffman");
FileInputStream fs = new FileInputStream(f);
byte[] buffer = new byte[1024];
int len = 0;
StringBuilder sb = new StringBuilder();
byte z = (byte)fs.read();
while ((len = fs.read(buffer)) != -1) {
for ( int i = 0; i < len; i++) {
sb.append(decode(buffer[i]));
}
}
fs.close();
return sb.substring(0, sb.length() - z);
}
}
c++ 版本
#include "stdafx.h"#include <stdio.h>
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
unsigned char encode(const char *s) {
int a = 0;
for ( int i = 0; i < 8; i++) {
if (s[i] == '1') {
a = a | (0x1 << (7 - i));
}
}
return (unsigned char)a;
}
void decode(unsigned char a, char *buf) {
for ( int i = 0; i < 8; i++) {
buf[i] = (((a >> (7 - i)) & 0x1) != 0) ? '1' : '0';
}
}
void writeHuffman(const string& s) {
unsigned char z = 8 - s.length() % 8;
if (z == 8) {
z = 0;
}
unsigned char buffer[1024];
buffer[0] = z;
int pos = 1, nBytes = (int)(ceil(s.length() / ((double)8)));
const char* ps = s.c_str();
FILE *fp = fopen("test.huffman", "wb");
char extended[8];
for ( int i = 0; i < nBytes; i++) {
const char *p;
if (s.length() >= (i + 1) * 8) {
p = ps + i * 8;
}
else {
char *pp = extended;
for ( int j = i * 8; j < s.length(); j++) {
*pp = s[j];
pp++;
}
for (int j = 0; j < z; j++) {
*pp = '0';
pp++;
}
p = extended;
}
buffer[pos] = encode(p);
pos++;
if (pos == 1024) {
fwrite(buffer, sizeof(unsigned char), 1024, fp);
pos = 0;
}
}
if (pos > 0) {
fwrite(buffer, sizeof(unsigned char), pos, fp);
}
fclose(fp);
}
string& readHuffman() {
FILE *fp = fopen("test.huffman", "rb");
fseek(fp, 0L, SEEK_END);
size_t fileSize = ftell(fp);
rewind(fp);
unsigned char buffer[1024];
fread(buffer, sizeof(unsigned char), 1, fp);
unsigned char z = buffer[0];
size_t stringSize = (fileSize - 1) * 8;
char *ptr = new char[stringSize + 1];
char *optr = ptr;
size_t len;
while ((len = fread(buffer, sizeof(unsigned char), 1024, fp)) != 0) {
for ( int i = 0; i < len; i++) {
decode(buffer[i], ptr);
ptr = ptr + 8;
}
}
fclose(fp);
ptr = ptr - z;
*ptr = '\0';
string* str = new string(optr);
delete []optr;
return *str;
}
int main(void)
{
writeHuffman("00010");
cout << readHuffman() << endl;
getchar();
return 0;
}
温馨提示:答案为网友推荐,仅供参考