压缩算法LZW

LZW算法

步骤如下:

初始化字典:创建一个初始字典,其中包含所有可能的输入符号。

输入处理:读取输入数据,并将第一个输入符号作为当前模式。

模式匹配和字典更新:从输入中读取下一个符号,并将当前模式与已有字典中的模式进行匹配。

如果匹配成功,将当前模式与下一个输入符号拼接,得到一个新的模式,继续进行匹配。
如果匹配失败,将当前模式的编码输出,并将当前模式与下一个输入符号作为新的模式。
编码输出:将最后一个匹配成功的模式的编码输出。

字典更新:将最后一个匹配成功的模式与下一个输入符号拼接,将这个新的模式添加到字典中。

重复步骤3-5,直到所有输入数据被处理完毕。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_DICT_SIZE 4096typedef struct {int code;char* pattern;
} Entry;void compress(FILE* inputFile, FILE* outputFile) {Entry dict[MAX_DICT_SIZE];int dictSize = 256;  // 初始字典大小为256,表示ASCII字符// 初始化字典for (int i = 0; i < 256; i++) {dict[i].code = i;dict[i].pattern = (char*)malloc(2 * sizeof(char));dict[i].pattern[0] = (char)i;dict[i].pattern[1] = '\0';}int currentCode = 0;  //0char currentSymbol;char nextSymbol;char* currentPattern = (char*)malloc(2 * sizeof(char));currentPattern[0] = fgetc(inputFile); //初始状态,字典里只有所有的默认项currentPattern[1] = '\0';while ((nextSymbol = fgetc(inputFile)) != EOF) {char* nextPattern = (char*)malloc((strlen(currentPattern) + 2) * sizeof(char));strcpy(nextPattern, currentPattern);strncat(nextPattern, &nextSymbol, 1);//读入新的字符C,与P合并形成字符串P+Cint found = 0;for (int i = 0; i < dictSize; i++) {// 在字典里查找P+Cif (strcmp(dict[i].pattern, nextPattern) == 0) {currentPattern = nextPattern;found = 1;   //P+C在字典里break;}}if (!found) {//P+C不在字典里,将P的记号输出;在字典中为P+C建立一个记号映射;更新P=Cfwrite(&dict[currentCode].code, sizeof(int), 1, outputFile);if (dictSize < MAX_DICT_SIZE) {dict[dictSize].code = dictSize;dict[dictSize].pattern = (char*)malloc((strlen(nextPattern) + 1) * sizeof(char));strcpy(dict[dictSize].pattern, nextPattern);dictSize++;}currentPattern = (char*)malloc(2 * sizeof(char));currentPattern[0] = nextSymbol;currentPattern[1] = '\0';currentCode = nextSymbol;}}fwrite(&dict[currentCode].code, sizeof(int), 1, outputFile);// 释放内存for (int i = 0; i < dictSize; i++) {free(dict[i].pattern);}free(currentPattern);
}int main() {FILE* inputFile = fopen("input.txt", "r");FILE* compressedFile = fopen("compressed.bin", "wb");compress(inputFile, compressedFile);fclose(inputFile);fclose(compressedFile);return 0;
}
#include <iostream>
#include <string>
#include <cstring>#define NotExist -1
#define MaxSize 1000using namespace std;typedef struct Dictionary{char	**seq;		// 字符串集合int		*code;		// 字符串编码的集合int		size;		// 字典的大小int		maxsize;	// 字典的最大长度
}Dictionary, *PDictionary;// 向字典中插入一条数据
void insert_seq(PDictionary dict, int code, char* seq)
{if (dict->size == dict->maxsize){printf("字典已满,插入失败!");return;}int i = dict->size;dict->code[i] = code;dict->seq[i] = (char*)malloc(sizeof(char) * strlen(seq) + 1);strcpy(dict->seq[i], seq);dict->size++;return;
}// 初始化字典
void initDict(PDictionary dict, int maxsize)
{dict->maxsize = maxsize;dict->size = 0;dict->code = (int*)malloc(sizeof(int) * maxsize);dict->seq = (char**)malloc(sizeof(char*) * maxsize + 1);// 初始化时先放入‘A’~‘Z’char seq[2] = "A";for (int i = 0; i < 26; i++){insert_seq(dict, i, seq);seq[0]++;}return;
}// 打印字典
void print_dict(PDictionary dict)
{printf("===================\n");printf("Code            Seq\n");for (int i = 0; i < dict->size; i++){printf("%4d%7s\n", dict->code[i], dict->seq[i]);}return;
}// 查找字典中有无seq
int is_exist_seq(PDictionary dict, char *seq)
{for (int i = 0; i < dict->size; i++){if (strcmp(seq, dict->seq[i]) == 0){return dict->code[i];}}return NotExist;
}// 根据编码查找Seq
char* find_seq(PDictionary dict, int code)
{return dict->seq[code];
}// LZW编码
void lzw_encode(PDictionary dict, char* text)
{char cur[MaxSize];char next;int code;char seq[MaxSize];int i = 0;int len = strlen(text);while (i < len){sprintf(cur, "%c", text[i]);while (is_exist_seq(dict, cur) != NotExist && i < len){i++;sprintf(cur, "%s%c", cur, text[i]);}if (i < len) {insert_seq(dict, dict->size, cur);cur[strlen(cur) - 1] = '\0';}code = is_exist_seq(dict, cur);printf("%d,", code, cur);}return;
}// LZE解码
void lzw_decode(PDictionary dict, int *code, int size)
{char *pre = NULL;int i = 0;char str[MaxSize];while (i < size){strcpy(str, find_seq(dict, code[i]));printf("%s", str);if (pre != NULL){char tmp[MaxSize];sprintf(tmp, "%s%c", pre, str[0]);insert_seq(dict, dict->size, tmp);}pre = (char*)malloc(sizeof(char) * strlen(str) + 1);strcpy(pre, str);i++;}printf("\n");return;
}int main()
{Dictionary dict;int code[] = { 8, 11, 14, 21, 4, 24, 14, 20, 26, 28, 30, 32, 3, 14, 31, 20, 27, 29, 12, 4, 38, 40, 42, 4, 44 };int size = 25;initDict(&dict, MaxSize);//lzw_encode(&dict, "ILOVEYOUILOVEYOUDOYOULOVEMEDOYOULOVEME");lzw_decode(&dict, code, size);//print_dict(&dict);return 0;
}

JPEG压缩算法

步骤如下:

将彩色图像转换为亮度和色度分量。对于彩色图像,首先将其转换为亮度(Y)和色度(Cb和Cr)分量,以便对亮度和色度进行独立的压缩。

对每个分量进行图像分块。将亮度和色度分量划分为8x8的图像块。

对每个图像块进行离散余弦变换(DCT)。对于每个8x8的图像块,应用离散余弦变换,将图像从空域转换到频域。

对DCT系数进行量化。将DCT系数进行量化,减少高频成分的精度,从而实现数据的压缩。

进行熵编码。对量化后的DCT系数进行熵编码,使用哈夫曼编码或其他熵编码算法来实现数据的进一步压缩。

重构图像。解码器根据压缩数据和解码过程的逆操作,对量化系数进行逆量化和逆DCT变换,以重构原始图像。

# 导入所需的库
import numpy as np
from scipy.fftpack import dct# 定义JPEG压缩函数
def jpeg_compress(image):# 将图像块划分为8x8的块blocks = image.reshape(-1, 8, 8)# 对每个图像块进行DCT变换dct_blocks = np.zeros_like(blocks)for i in range(blocks.shape[0]):dct_blocks[i] = dct(dct(blocks[i], axis=0), axis=1)# 对DCT系数进行量化quantized_blocks = np.round(dct_blocks / quantization_table)# 对量化后的系数进行熵编码等进一步压缩步骤# 返回压缩后的数据return quantized_blocks# 定义量化表
quantization_table = np.array([[16, 11, 10, 16, 24, 40, 51, 61],[12, 12, 14, 19, 26, 58, 60, 55],[14, 13, 16, 24, 40, 57, 69, 56],[14, 17, 22, 29, 51, 87, 80, 62],[18, 22, 37, 56, 68, 109, 103, 77],[24, 35, 55, 64, 81, 104, 113, 92],[49, 64, 78, 87, 103, 121, 120, 101],[72, 92, 95, 98, 112, 100, 103, 99]
])# 读取图像数据
image = read_image("input.jpg")# 调用JPEG压缩函数
compressed_data = jpeg_compress(image)# 保存压缩后的数据
save_compressed_data(compressed_data, "compressed.jpg")

无损压缩算

哈夫曼编码:具有较高的压缩比率和解压速度,适用于文本数据和较小的数据集。质量无损。
LZW算法:具有较高的压缩比率和解压速度,适用于文本和图像数据。质量无损。
预测编码:如算术编码和差分编码,压缩比率较高,但解压速度较慢。质量无损。

有损压缩算法:

JPEG压缩算法:适用于图像压缩,具有较高的压缩比率和解压速度,但会引入一定的图像质量损失。
MP3压缩算法:适用于音频压缩,具有较高的压缩比率和解压速度,但会引入一定的音质损失。
视频编码算法:如H.264、HEVC等,具有较高的压缩比率和解压速度,但会引入一定的视频质量损失
RLE(Run Length Encoding)
文件内容——数据*重复次数

ABCDEFG经压缩后将成为1A1B1C1D1E1F1G,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/39249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高性价比宠物空气净化器分享,希喂、霍尼韦尔、有哈PK

近期&#xff0c;家中的小猫咪仿佛化身为行走的“蒲公英”&#xff0c;掉毛现象愈发严重&#xff0c;家中每个角落乃至空气中都弥漫着难以忽视的猫毛&#xff0c;衣物更是无一幸免&#xff0c;披上了毛茸茸的“外衣”。更令人啼笑皆非的是&#xff0c;就连不经意间清理的眼屎中…

React 组件 API

React 组件 API React 组件 API 是 React 应用程序开发中的核心部分&#xff0c;它提供了一系列的接口和方法&#xff0c;使得开发者能够创建和管理组件的状态、属性以及生命周期。在本篇文章中&#xff0c;我们将深入探讨 React 组件 API 的各个方面&#xff0c;包括组件的定…

VQA视觉问答系统

这是一个典型的多模态问题,融合了CV与NLP的技术,计算机需要同时学会理解图像和文字。 Joint embedding 首先,图像和问题分别由CNN和RNN进行第一次编码得到各自的特征,随后共同输入到另一个编码器中得到joint embedding,最后通过解码器输出答案。 值得注意的是,有的工作…

k8s 答疑

1 如何修复容器中的 top 指令以及 /proc 文件系统中的信息呢? 这段自问自答的内容解释了如何通过使用 lxcfs 来修复 Docker 容器中 top 指令和 /proc 文件系统中的信息。让我们分步骤来详细说明: 背景信息 在容器化环境中,通常会遇到一个问题,即容器中的一些命令(如 to…

Java核心技术【十八】Java集合框架精讲:List、Set、Map

Java集合框架精讲&#xff1a;List、Set、Map的使用详解与代码示例 Java集合框架是Java编程中不可或缺的一部分&#xff0c;它提供了一系列容器类&#xff0c;用于存储和操作不同类型的数据集。在Java集合框架中&#xff0c;List、Set和Map是最常用的三种集合类型&#xff0c;…

小红书运营教程02

小红书大致会分享10篇左右。微博、抖音、以及视频剪辑等自媒体运营相关技能以及运营教程相关会陆续的进行分享。 上次分享涉及到的对比,母婴系列,或者可以说是服装类型,不需要自己过多的投入,对比知识类博主来说,自己将知识讲述出来,然后要以此账号进行变现就比较麻烦,…

道可云元宇宙每日资讯|山东出台人形机器人产业发展路线

道可云元宇宙每日简报&#xff08;2024年7月1日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 山东出台人形机器人产业发展路线 近期&#xff0c;山东省工业和信息化厅等部门印发《山东省促进人形机器人产业创新发展实施方案&#xff08;2024—2027年&#xff0…

如果这时你还不清理C盘,那只能眼睁睁看着电脑越来越卡 直到系统崩溃

如果这时候你还不清理C盘&#xff0c;那只能眼睁睁看着电脑越来越卡 直到系统崩溃。很多人就是想偷懒&#xff0c;当然这是人的天性&#xff0c;明明知道自己的C盘空间就那么大&#xff0c;一天天看着C盘空间越来越小&#xff0c;还不去清理C盘。 这样的人有两种&#xff0c;一…

CesiumJS【Basic】- #048 绘制闪烁线(Primitive方式)

文章目录 绘制闪烁线(Primitive方式)- 需要自定义着色器1 目标2 代码2.1 main.ts绘制闪烁线(Primitive方式)- 需要自定义着色器 1 目标 使用Primitive方式绘制闪烁线 2 代码 2.1 main.ts import * as Cesium from cesium;const viewer = new Cesiu

软件开发案例参考

前言&#xff1a;基于平台现有需求进行新功能模块开发与实现&#xff0c;以下内容为部分源码解析&#xff0c;仅提供一些思路参考&#xff0c;不予以客观指导&#xff0c;毕竟条条大路通罗马嘛&#xff1b; 语言&#xff1a;C# 工具&#xff1a;visual studio 2017/visual st…

【MySQL List插入】MySQL List格式数据插入

其中id为对应的函数名&#xff0c;useGeneratedKeys是否主键自动生成&#xff0c;keyProperty主键关联的属性。 <foreach collection"list" item"element" index"index" separator",">确定集合类型&#xff0c;item每个元素表示…

C++基础(二):C++入门(一)

C是在C的基础之上&#xff0c;容纳进去了面向对象编程思想&#xff0c;并增加了许多有用的库&#xff0c;以及编程范式 等。熟悉C语言之后&#xff0c;对C学习有一定的帮助&#xff0c;本篇博客主要目标&#xff1a; 1. 补充C语言语法的不足&#xff0c;以及C是如何对C语言设计…

【RabbitMQ实战】邮件发送(直连交换机、手动ack)

一、实现思路 二、异常情况测试现象及解决 说明:本文涵盖了关于RabbitMQ很多方面的知识点, 如: 消息发送确认机制 、消费确认机制 、消息的重新投递 、消费幂等性, 二、实现思路 1.简略介绍163邮箱授权码的获取 2.编写发送邮件工具类 3.编写RabbitMQ配置文件 4.生产者发起调用…

高考失利咨询复读,银河补习班客服开挂回复

补习班的客服在高考成绩出来后&#xff0c;需要用专业的知识和足够的耐心来回复各种咨询&#xff0c;聊天宝快捷回复软件&#xff0c;帮助客服开挂回复。 ​ 前言 高考成绩出来&#xff0c;几家欢喜几家愁&#xff0c;对于高考失利的学生和家长&#xff0c;找一个靠谱的复读补…

全面了解机器学习

目录 一、基本认识 1. 介绍 2. 机器学习位置 二、机器学习的类型 1. 监督学习 2. 无监督学习 3. 强化学习 三、机器学习术语 1. 训练样本 2. 训练 3. 特征 4. 目标 5. 损失函数 四、机器学习流程 五、机器学习算法 1. 分类算法 2. 聚类算法 3. 关联分析 4. …

Qt入门教程(一):Qt使用的基本知识

目录 Qt简介 新建项目 构建目录和工作目录 构建目录 工作目录 项目结构 项目配置文件 .pro 用户文件 .user 主文件 main.cpp 头文件 dialog.h 源文件 dialog.cpp 帮助文档 三种查询文档的方式&#xff1a; 文档的重点位置&#xff1a;​编辑 调试信息 Qt简介 Qt…

java 代码块

Java中的代码块主要有三种类型&#xff1a;普通代码块、静态代码块、构造代码块。它们的用途和执行时机各不相同。 普通代码块&#xff1a;在方法内部定义&#xff0c;使用一对大括号{}包围的代码片段。它的作用域限定在大括号内&#xff0c;每当程序执行到该代码块时就会执行其…

全平台7合一自定义小程序源码系统功能强大 前后端分离 带完整的安装代码包以及搭建教程

系统概述 这款全平台 7 合一自定义小程序源码系统是专为满足各种业务需求而设计的。它整合了多种功能&#xff0c;能够在不同平台上运行&#xff0c;为用户提供了全方位的体验。无论你是企业主、开发者还是创业者&#xff0c;这款系统都能为你提供强大的支持。 代码示例 系统…

crewAI实践(包含memory的启用)--AiRusumeGenerator

crewAI实践--AiRusumeGenerator 什么是crewAIAiRusumeGenerator功能效果展示开发背景开发步骤1. 首先得学习下这款框架原理大概用法能够用来做什么&#xff1f; 2. 安装crewAI以及使用概述3. 写代码Agents.pyTasks.pymian.py关于task中引入的自定义工具这里不再赘述 什么是crew…

C# 截取图片

C#从图中截取部分图片 代码实现截图_c# net core webapi如何通过图片大小区域范围进行截图-CSDN博客