左神算法基础班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;
}

一种整型数值的压缩算法相关推荐

  1. Java 和 .NET 获得毫秒级长整型数值的差异和解决

    2019独角兽企业重金招聘Python工程师标准>>> 维护的某系统中有个用 Java 写的生成唯一标识的类,主要是靠"Calendar.getInstance().get ...

  2. MySQL 五种整型数据类型的范围与区别 tinyint smallint mediumint int bigint

    之前在论坛上看到一个有意思的问题,如果有一个字段的值超过bigint,会发生什么. 然后就看到有人喷,说0.1秒插入一个值,将bigint设置为无符号,插入到极限需要多久,根本不可能遇到如何如何 . ...

  3. c语言的数据类型有什么 long int,C语言的三种整型数据类型:INT SHORT INT和LONG INT...

    int数据类型的位数为16位,short int数据类型的位数也是16位.而long int的位数为32位,可用来存储比较大的整数. short int和long int可以缩写为short和long ...

  4. C语言的三种整型数据类型:int、short int和long int

    int数据类型的位数为16位,short int数据类型的位数也是16位.而long int的位数为32位,可用来存储比较大的整数. short int 和 long int可以缩写为short 和 ...

  5. c语言的数据类型有什么 long int,C语言的三种整型数据类型:int、short_int和long_int...

    int数据类型的位数为16位,short int数据类型的位数也是16位.而long int的位数为32位,可用来存储比较大的整数. short int 和 long int可以缩写为short 和 ...

  6. java int转无符号_Java中int或long等整型数值如何转换为无符号整数

    Java8 为 Integer.Long包装类增加了如下方法: static  String  toUnsignedString(int/long i):将指定int或long型整数转换为无符号整数对 ...

  7. ABAP里几种整型数据类型的范围和转换

  8. python语言中整型对应的英文是什么-12.Python数值类型(整形、浮点型和复数)及其用法...

    实际开发中,我们经常需要使用数字记录游戏中用户的得分.游戏中角色的生命值.伤害值等信息,Python 语言提供了数值类型用于保存这些数值. 需要注意的是,Python 中这些数值类型都是不可改变的,也 ...

  9. python整型转化浮点型_Python数值类型(整形、浮点型和复数)及其用法

    数值类型是计算机程序最常用的一种类型,既可用于记录各种游戏的分数.游戏角色的生命值.伤害值等,也可记录各种物品的价格.数量等,Python 提供了对各种数值类型的支持,如支持整型.浮点型和复数. Py ...

最新文章

  1. Microsoft 顺序分析和聚类分析算法
  2. 详解vue生命周期及每个阶段适合进行的操作
  3. 《Effective Java》 第二讲:对于所有对象都通用的方法
  4. pytorch-word2vec的实例实现
  5. Branch management
  6. RHEL 7.0已发布 CentOS 7 即将到来
  7. android:inputType参数类型说明
  8. java 学习之List 的 add 与set方法区别
  9. 排序之插入排序(二分法)
  10. K3S配置IPV6环境
  11. groovy简单介绍
  12. ubuntu 您不是所有者所以您不能更改
  13. MFC:读取整个记事本文件
  14. oracle从11.0.2.4.0打PSU 11.0.2.4.8
  15. Windows Workflow Foundation中实现人工活动的demo,按照XPDL规范的实现
  16. 12道Java高级面试题:java时间差计算
  17. 测试光流传感器速度特性
  18. 经典散文·1.地毯的那一端
  19. 关于SCO Unix 串口通讯
  20. 2022全网最全Java面试题-小米社招面试经验java,面试题整理(一面二面)

热门文章

  1. Dev-c++语言设置成中文的方式
  2. 电脑如何远程连接服务器
  3. JavaScript 三目运算符 return不合语法
  4. 吃鸡信号枪服务器,绝地求生八人组队新模式介绍,信号枪正式上线服务器!
  5. 一些比较新的图像去噪论文(2020)
  6. Dust3D项目实训五 | 基于modeloffscreenrender的画面渲染分析
  7. 埃及旅游游记: 欣赏世界最古老的纸画
  8. 关于先验概率和后验概率的通俗解释。
  9. Inkscape扩展:图案沿着路径和散布
  10. c语言中的反余弦和反正弦函数,VB中的反正弦函数与反余弦函数