一种整型数值的压缩算法
左神算法基础班C++实现目录
- 1.压缩算法
- 原理
- 代码
- 2.解压缩算法
- 原理
- 代码
- 3.完整代码
int类型的表示范围从0~4294967295,共占用四个字节。而在实际处理中,某些较小的数在除了真正存储的数值以外,其他字节填充值为0,例如7的二进制表示如下,如何将未用上的前三个字节去掉以便节省空间呢?
1.压缩算法
原理
下图①表示整数67335中四个字节实际存储的数据,本压缩算法将每个字节的最高位作为标志位标识整型数值是否结束,未结束置1,结束置0。从低位向高位类推,每个字节都有一位不进行存储,那么四个字节共计有四位需要单独存储。也就是说,本压缩算法能够将4个字节的数值压缩为1~5个字节。
将67335按照七位进行划分,得到②。从右侧向左侧进行填充标志位,67335按照七位划分共存储三个字节,后两个标志位置1,前三个标志位置0,得到③。最后留下实际存储不为0的字节,得到④即压缩后的字节。
再举一个例子:将255压缩
255作为int类型存储如①,将其按照七位划分占用两个字节存储②,将后一个字节标志位置1,将前一个字节标志位置0表示存储结束③,最终结果如④
代码
根据原理说明,需要从后向前按七位进行划分,如果除掉此七位剩余的数值还不为0则说明为存储未结束,将标志位置1,如果数值为0,表示存储结束,标志位置0。
假设传入的值为value
获取后七位的数值c:可以使用c = value & 0x7f
按七位进行一次划分:可以使用右移value>>=7
将标志位置1:c |= 0x80
整理一下
unsigned char buf[100];
int len = 0;
void test_compress(int value) {do {unsigned char c = (unsigned char)(value&0x7f); //获取后七位value >>= 7; //获取余下的值if (value)c |= 0x80; //值不为0表示为存储完将标志位置1buf[len++] = c; //存储这一个字节,实际是7位数据加1个标志位} while (value); //余下值不为0继续存储
}
注意:由于是按位操作,需要打印函数查看是否正确
- 打印原始数据二进制的
print_ori
函数
此函数每8位加一个空格进行划分
void print_ori(int c) {for (int i = 31; i >= 0; i--) {if (i == 7 || i == 15 || i == 23)cout << " ";if (0 != (c >> i & 0x1))cout << "1";elsecout << "0";}printf("\n");
}
- 打印一个字节二进制的
print_one_byte
函数
此函数在do while
循环中打印处理的这个字节
void print_one_byte(unsigned char c){for (int i = 7; i >= 0; i--) {if (0 != (c >> i & 0x1))cout << "1";elsecout << "0";}printf(" ");
}
压缩算法完整代码
#include<iostream>
using namespace std;
unsigned char buf[100];
int len = 0;void print_ori(int c) {for (int i = 31; i >= 0; i--) {if (i == 7 || i == 15 || i == 23)cout << " ";if (0 != (c >> i & 0x1))cout << "1";elsecout << "0";}printf("\n");
}void print_one_byte(unsigned char c){for (int i = 7; i >= 0; i--) {if (0 != (c >> i & 0x1))cout << "1";elsecout << "0";}printf(" ");
}void test_compress(int value) {do {unsigned char c = (unsigned char)(value&0x7f);value >>= 7;if (value)c |= 0x80;print_one_byte(c);buf[len++] = c;} while (value);
}int main() {int ori = 255;print_ori(ori);test_compress(ori);return 0;
}
上一行是255的原始数据打印,下一行是压缩后的结果
2.解压缩算法
原理
解压缩是压缩的一个逆过程,首先一个一个字节读取压缩后的数c
并获取后七位(x = c & 0x7f
);将得到的值存入value
,如果c
的标志位为1则继续读取,否则结束。需要注意的是,由于压缩从后向前存储7位,所以每次读出的数需要先递增左移(第一次左移0位,第二次左移7位,第三次左移14位,第四次左移21位,第五次左移28位)再进行存储。
代码
void test_uncompress(){char c; //单个字节的数值int len = 0; //从buf中读取的位置int s = 0; //左移变量,每次增加7int value = 0; //存储实际的值do {c = buf[len++];unsigned int x = (c & 0x7f); //获取后七位x <<= s; //左移value += x; //存入values += 7; } while (c & 0x80); //判断标志位printf("%d\n", value);
}
3.完整代码
包括四个函数:
- print_ori:将四个字节的int按照二进制进行打印
- print_one_byte:打印一个字节
- test_compress压缩算法,输入int型数值value,将压缩后的数值存入buf
- test_uncompress解压缩算法,读取buf中压缩的数值,解压缩为int
#include<iostream>
using namespace std;
unsigned char buf[100];
int len = 0;void print_ori(int c) {for (int i = 31; i >= 0; i--) {if (i == 7 || i == 15 || i == 23)cout << " ";if (0 != (c >> i & 0x1))cout << "1";elsecout << "0";}printf("\n");
}void print_one_byte(unsigned char c){for (int i = 7; i >= 0; i--) {if (0 != (c >> i & 0x1))cout << "1";elsecout << "0";}printf(" ");
}void test_compress(int value) {do {unsigned char c = (unsigned char)(value & 0x7f); //获取后七位value >>= 7; //获取余下的值if (value)c |= 0x80; //值不为0表示为存储完将标志位置1print_one_byte(c);buf[len++] = c; //存储这一个字节,实际是7位数据加1个标志位} while (value); //余下值不为0继续存储
}void test_uncompress(){char c; //单个字节的数值int len = 0; //从buf中读取的位置int s = 0; //左移变量,每次增加7int value = 0; //存储实际的值do {c = buf[len++];unsigned int x = (c & 0x7f); //获取后七位x <<= s; //左移value += x; //存入values += 7; } while (c & 0x80); //判断标志位printf("%d\n", value);
}int main() {int ori = 67335;cout << "ori: " <<ori << endl;print_ori(ori);cout << "compress: " << endl;test_compress(ori);cout << endl<<"uncompress: " ;test_uncompress();return 0;
}
一种整型数值的压缩算法相关推荐
- Java 和 .NET 获得毫秒级长整型数值的差异和解决
2019独角兽企业重金招聘Python工程师标准>>> 维护的某系统中有个用 Java 写的生成唯一标识的类,主要是靠"Calendar.getInstance().get ...
- MySQL 五种整型数据类型的范围与区别 tinyint smallint mediumint int bigint
之前在论坛上看到一个有意思的问题,如果有一个字段的值超过bigint,会发生什么. 然后就看到有人喷,说0.1秒插入一个值,将bigint设置为无符号,插入到极限需要多久,根本不可能遇到如何如何 . ...
- c语言的数据类型有什么 long int,C语言的三种整型数据类型:INT SHORT INT和LONG INT...
int数据类型的位数为16位,short int数据类型的位数也是16位.而long int的位数为32位,可用来存储比较大的整数. short int和long int可以缩写为short和long ...
- C语言的三种整型数据类型:int、short int和long int
int数据类型的位数为16位,short int数据类型的位数也是16位.而long int的位数为32位,可用来存储比较大的整数. short int 和 long int可以缩写为short 和 ...
- c语言的数据类型有什么 long int,C语言的三种整型数据类型:int、short_int和long_int...
int数据类型的位数为16位,short int数据类型的位数也是16位.而long int的位数为32位,可用来存储比较大的整数. short int 和 long int可以缩写为short 和 ...
- java int转无符号_Java中int或long等整型数值如何转换为无符号整数
Java8 为 Integer.Long包装类增加了如下方法: static String toUnsignedString(int/long i):将指定int或long型整数转换为无符号整数对 ...
- ABAP里几种整型数据类型的范围和转换
- python语言中整型对应的英文是什么-12.Python数值类型(整形、浮点型和复数)及其用法...
实际开发中,我们经常需要使用数字记录游戏中用户的得分.游戏中角色的生命值.伤害值等信息,Python 语言提供了数值类型用于保存这些数值. 需要注意的是,Python 中这些数值类型都是不可改变的,也 ...
- python整型转化浮点型_Python数值类型(整形、浮点型和复数)及其用法
数值类型是计算机程序最常用的一种类型,既可用于记录各种游戏的分数.游戏角色的生命值.伤害值等,也可记录各种物品的价格.数量等,Python 提供了对各种数值类型的支持,如支持整型.浮点型和复数. Py ...
最新文章
- Microsoft 顺序分析和聚类分析算法
- 详解vue生命周期及每个阶段适合进行的操作
- 《Effective Java》 第二讲:对于所有对象都通用的方法
- pytorch-word2vec的实例实现
- Branch management
- RHEL 7.0已发布 CentOS 7 即将到来
- android:inputType参数类型说明
- java 学习之List 的 add 与set方法区别
- 排序之插入排序(二分法)
- K3S配置IPV6环境
- groovy简单介绍
- ubuntu 您不是所有者所以您不能更改
- MFC:读取整个记事本文件
- oracle从11.0.2.4.0打PSU 11.0.2.4.8
- Windows Workflow Foundation中实现人工活动的demo,按照XPDL规范的实现
- 12道Java高级面试题:java时间差计算
- 测试光流传感器速度特性
- 经典散文·1.地毯的那一端
- 关于SCO Unix 串口通讯
- 2022全网最全Java面试题-小米社招面试经验java,面试题整理(一面二面)