lz77编码的c语言实现,[数据结构和算法]LZ77压缩算法三部曲——1.KMP算法(C语言)...

KMP算法的理论部分就不在赘述了,有不懂的小伙伴可以参考这个帖子,感觉写的挺不错的。从头到尾彻底理解KMP

个人比较喜欢简单粗暴的直接上代码,又看不懂的小伙伴可以下下面评论提出来。

下面的程序是为了后面的LZ77 压缩算法做铺垫的,其实现的是从源数据中找到与匹配数据最长的数据的坐标和匹配长度。绕的有点晕哈;

举个栗子:

字符串s = “a b a c a a b a c a b a c a b a a b b”;

字符串p = “a b a c a b”;

从字符串s中找到与字符串p匹配的数据的下标和最长匹配数据长度;

#include

#include

#include

#include

typedef unsigned char uchar;

typedef unsigned short ushort;

typedef unsigned int uint;

#define TEST_STR0//选择测试对象是字符串还是数组

typedef struct KMP{

uchar *src; //源数据

uchar *dst;//要求匹配的数据

ushort sLen;//源数据长度

ushort pLen;//匹配数据长度

ushort coord;//匹配到数据记录其坐标

ushort matchLen; //最大的匹配长度

}KMP_TypeDef;

KMP_TypeDef KMP;

bool KMP_Search(KMP_TypeDef *KMP){

int i=0,j=0,max=0,baki=0;

if(KMP->sLen==0 || KMP->pLen==0){

return false;

}

while(i < KMP->sLen){//把源数据遍历一遍

if(KMP->src[i] == KMP->dst[j]){//从源数据中找到与匹配数据相同的数据

i++;

j++;

if(j >= max){

max = j; //更新最长匹配数据长度

baki = i;//备份坐标值

}

}

else{

i = i - j + 1;

j = 0;//如果失配,则下一次匹配从匹配数据的第一个数据开始

}

}

KMP->coord = baki-max;//找到最佳匹配数据的下标

KMP->matchLen = max; //匹配数据长度

return true;

}

int main(void){

uchar str[100]={0};

KMP_TypeDef kmp;

#if TEST_STR

kmp.src = "a b a c a a b a c a b a c a b a a b b";//"ABCDEFGHIJKLMNOPQRSTUVWXYZd abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdesfghijklmnopqrstuvwxyz";//

kmp.dst = "a b a c a b";//"abcdesfghiu";//

kmp.sLen = strlen(kmp.src);

kmp.pLen = strlen(kmp.dst);

printf("slen:%d - plen:%d\n",kmp.sLen,kmp.pLen);

#else

uchar arr1[] = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f};

uchar arr2[] = {0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b};

kmp.sLen = sizeof(arr1)/sizeof(arr1[0]);

kmp.pLen = sizeof(arr2)/sizeof(arr2[0]);

kmp.src = malloc(kmp.sLen * sizeof(arr1[0]));

kmp.dst = malloc(kmp.pLen * sizeof(arr2[0]));

memcpy(kmp.src, arr1, kmp.sLen);

memcpy(kmp.dst, arr2, kmp.pLen);

printf("slen:%d - plen:%d\n",kmp.sLen,kmp.pLen);

#endif

KMP_Search(&kmp);

printf("coord:%d - Len:%d\n",kmp.coord, kmp.matchLen);//打印下标和长度

strncpy(str, kmp.dst, kmp.matchLen);//字符串拷贝,这里拷贝数据也没出错

printf("Match: %s\n",str);//打印字符串,测试数组也将打印成字符串,具体内容可以参照ASCII码表

}

测试结果

#define TEST_STR 0

d062f4d5c68a62d68422e3ee5ea605e4.png

#define TEST_STR 1

19e3d9339629c6350380f8f331d9ef2e.png

把字符串替换一下

kmp.src ="ABCDEFGHIJKLMNOPQRSTUVWXYZd abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdesfghijklmnopqrstuvwxyz";

kmp.dst = "abcdesfghiu";

2af08a2dda5f09963f59f87de0390359.png

不知道大家需不需要了解一下LZ77压缩算法的C语言实现程序,这样吧。有需要的小伙伴下面评论一下,或者博文浏览量超过1K再更新LZ77压缩算法,不然更新了没人看也悲哀啊

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值