Skip to content

compression-algorithm-research-lab/go-unary-coding

Repository files navigation

一元编码(go-unary-coding)

一、什么是一元编码

一元编码(Unary Coding)是一种只对非负整数进行编码的压缩算法,一个数字n的一元编码就是连续n个1后面跟着一个0作为分隔,或者连续n个0后面跟着一个1作为分隔,因为取值只有0和1,所以通常对应到一个bit,所以对正整数n进行一元编码,会占用n+1个bit(n个数据位+1个分隔位)。

比如对[2, 3, 1, 4]进行一元编码,连续部分采用1,分隔部分采用0,大概是下面这个样子:

image-20231212003008563

从上面的编码中我们能看出来,一元编码比较适合对大于2并且小于8的这个区间的数字进行编码,能够取得较好的压缩率。

二、安装

go get -u github.com/compression-algorithm-research-lab/go-unary-coding

三、API示例

package main

import (
	"fmt"
	unary_coding "github.com/compression-algorithm-research-lab/go-unary-coding"
	"math/rand"
)

func main() {

	// 压缩单个的数字
	encode := unary_coding.Encode[uint](1)
	fmt.Println(encode)

	// 压缩整数数组
	slice := unary_coding.EncodeSlice([]uint{1, 2, 3, 4})
	fmt.Println(slice)

	fmt.Println("---------------------------------------------------------")

	// 基于频率压缩,适合数字分布在某个较小的区间范围内
	nums := make([]uint, 0)
	for i := 0; i < 100; i++ {
		n := rand.Int()%10 + 1000
		nums = append(nums, uint(n))
	}
	fmt.Printf("原始的数组: %v \n", nums)
	// 原始的数组: [1008 1001 1008 1003 1009 1004 1004 1003 1008 1003 1007 1003 1004 1001 1001 1006 1008 1005 1005 1004 1005 1009 1002 1009 1004 1001 1009 1003 1002 1002 1000 1009 1005 1009 1003 1000 1009 1000 1003 1003 1005 1004 1008 10
	//09 1002 1003 1001 1001 1007 1009 1004 1002 1008 1003 1009 1005 1005 1005 1009 1003 1007 1007 1009 1005 1008 1000 1000 1000 1006 1005 1003 1002 1001 1003 1006 1001 1002 1009 1008 1005 1001 1005 1000 1003 1009 1000 1008 1001 1008 100
	//2 1006 1001 1002 1005 1005 1005 1001 1009 1008 1001]

	compressedBytes, weights := unary_coding.EncodeSliceWithFrequency(nums)
	fmt.Printf("压缩完之后的字节数组: %v \n", compressedBytes)
	// 压缩完之后的字节数组: [251 223 117 254 255 119 221 255 119 251 222 255 223 109 254 215 235 253 235 191 126 254 181 223 215 247 118 255 125 126 239 123 254 191 223 190 235 109 119 253 255 91 239 239 239 239 253 187 247 187 255 123
	//245 246 246 254 235 251 239 125 251 255 123 246 219 215 222]

	fmt.Printf("压缩完之后的字节数组大小: %d \n", len(compressedBytes))
	// 压缩完之后的字节数组大小: 67

	fmt.Printf("权重数组: %v \n", weights)
	// 权重数组: [1009 1005 1003 1001 1008 1002 1000 1004 1007 1006]

	rawNums := unary_coding.DecodeSliceWithFrequency(compressedBytes, weights)
	fmt.Printf("解压之后的数组: %v \n", rawNums)
	// 解压之后的数组: [1008 1001 1008 1003 1009 1004 1004 1003 1008 1003 1007 1003 1004 1001 1001 1006 1008 1005 1005 1004 1005 1009 1002 1009 1004 1001 1009 1003 1002 1002 1000 1009 1005 1009 1003 1000 1009 1000 1003 1003 1005 1004 100
	//8 1009 1002 1003 1001 1001 1007 1009 1004 1002 1008 1003 1009 1005 1005 1005 1009 1003 1007 1007 1009 1005 1008 1000 1000 1000 1006 1005 1003 1002 1001 1003 1006 1001 1002 1009 1008 1005 1001 1005 1000 1003 1009 1000 1008 1001 1008
	// 1002 1006 1001 1002 1005 1005 1005 1001 1009 1008 1001]

}

Releases

No releases published

Packages

No packages published

Languages