游程编码详解(C语言)

题目

给定一串数据,如:
0x11,0x22,0x11,0x11,0x11,0x34,0x34,0x22
编码后,得到:
0x11,0x01,0x22,0x01,0x11,0x03,0x34,0x02,0x22,0x01

数据分析

显然在给定的这一组数据中,他们都是占一个字节的字符型数据。所以我们肯定是要用数组来存储。同时我们要输出的数据也应该采用数组打印的方式来输出我们的结果

核心思想

在写的过程中时刻提问自己

  • 我操作的对象是什么?(即数据的类型,大小)
  • 分配的内存空间在那个段?(栈,堆,data(初始化,未初始化),常量)
  • 处理后在内存中的位置

完整代码

下面展示一些 内联代码片

#include<stdio.h>
#include <stdlib.h>//malloc函数需要引用该头文件
void *shifang(void *space){//用完以后我们要释放我们在堆上申请的空间
    free(space);
}
void *encoding(const void *raw,int *num){//函数声明,我们要想清楚,我们需要的到的是什么,我们要得到这个结果,需要外界给我们提供什么
    unsigned char *data=(unsigned char *)raw;  //因为上面我们定义的是 void类型,所以这里需要我们进行强制转换一下类型。
    unsigned char *result=NULL;//我们定义我们的返回结果,因为函数是在栈里面的,所以为了在函数结束后我们还能找到结果,我们需要将它放在堆里。
    //第一步,我们要找到result的长度,我们才能将结果存放在堆内
    int tmp=*num;
    unsigned char s=data[0];
    int count=1;
    for (int i = 1; i <tmp ; ++i) {
        if (data[i]!=s){
            count++;
            s=data[i];
        }
    }
    result=(char *)malloc(count*2);
    printf("This result length is %d\n",count*2);//这里可以检验一下我们是不是有错
    if (result==NULL){//检验堆内存分配是否成功
        printf("error!\n");
    }
    *num=count*2;//反向更新,将我们的result长度返回到main中的length去。类比scanf函数
    //进行数据的填充
    int foo=1;//用来帮助我们记录result的位置
    count=1;
    result[0]=data[0];
    s=data[0];
    for (int j = 1; j <tmp ; ++j) {
        if (data[j]!=s){
            result[foo]=count;
            foo++;
            count=1;//置1重新计数
            result[foo]=data[j];
            foo++;
            s=data[j];
        } else{
            count++;
        }
    }
    //进行收尾的处理
    result[foo]=count;
    return result;

}
int main(){
    //存储我们的数据
    char raw_data[]={0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x11, 0x11};
    char *result;//声明我们的结果
    //调用函数
    int length=sizeof(raw_data)/sizeof(raw_data[0]);
    result=encoding(raw_data,&length);
    if (result==NULL){//检验机制
        printf("error!\n");
        return -1;
    }
    for (int i = 0; i <length ; ++i) {//结果的显示,显然我们需要打印的长度,这个长度我们需要依靠函数告知,所以采用反向更新的思想
        printf("0x%x\t",result[i]);
    }
    printf("\n");
    shifang(result);
    return  0;
}

运行结果:

在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
RGB图像压缩可以采用游程编码(Run Length Encoding,RLE)算法。游程编码是一种无损压缩方法,可以将连续重复的数据序列转换为一组游程,从而减少数据的存储空间。 以下是基于游程编码对RGB进行压缩的C语言实现: ```c #include <stdio.h> #include <stdlib.h> #define MAX_RLE_LENGTH 255 // RLE压缩函数 unsigned char* RLECompress(unsigned char* data, int size, int* outSize) { int count = 1; int i, j; unsigned char* compressedData = (unsigned char*)malloc(MAX_RLE_LENGTH * 3 * sizeof(unsigned char)); if (compressedData == NULL) { printf("Memory allocation error!\n"); exit(1); } j = 0; for (i = 1; i < size; i++) { if (data[i] == data[i - 1] && count < MAX_RLE_LENGTH) { count++; } else { compressedData[j++] = data[i - 1]; compressedData[j++] = count; count = 1; } } compressedData[j++] = data[size - 1]; compressedData[j++] = count; *outSize = j; return compressedData; } int main() { int size = 9; unsigned char data[] = {255, 0, 0, 255, 255, 0, 255, 255, 255}; int compressedSize; unsigned char* compressedData = RLECompress(data, size, &compressedSize); printf("Original data: "); for (int i = 0; i < size; i++) { printf("%d ", data[i]); } printf("\n"); printf("Compressed data: "); for (int i = 0; i < compressedSize; i++) { printf("%d ", compressedData[i]); } printf("\n"); free(compressedData); return 0; } ``` 在上面的代码中,我们通过RLECompress函数对RGB数据进行压缩。该函数接收一个包含RGB数据的unsigned char数组,以及数组长度和一个输出参数outSize,它返回一个压缩后的unsigned char数组。该函数首先将连续重复的数据序列转换为一组游程,然后将压缩后的数据存储在一个新的数组中,并返回该数组。 在这个例子中,我们对一个包含RGB数据的unsigned char数组进行压缩,并输出原始数据和压缩后的数据。注意,这里的数据是单通道的,如果要对RGB图像进行压缩,需要将RGB数据分别进行压缩,或者采用其他的压缩方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jacky~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值