树的企业应用-哈夫曼编码树-有趣的数据压缩算法

news2025/1/10 2:54:31

树的企业应用-哈夫曼编码树-有趣的数据压缩算法

哈夫曼编码 描述

张三李四家里,但 李四是一个女生,所以张三李四去上海迪尼斯玩 …

亚历山大.张三伊丽莎白.李四家里,但 伊丽莎白.李四是一个女生,所以亚历山大.张三伊丽莎白.李四去美国迪尼斯玩 …

我们发现 一个关键点 有些重复的也不多 无非就高亮的地方 所以简化一下

声明一下 在上方的引言里 凡是出现高亮的 统统替换为 “张三” and “李四”

张三李四家里,但 李四是一个女生,所以张三李四去上海迪尼斯玩 ………

张三李四家里,但 李四是一个女生,所以张三李四去美国迪尼斯玩 ………

哈夫曼编码:把字符出现的次数压缩成只有一个

这就是哈夫曼编码 基本描述

哈夫曼编码树原理

字符串为 **"yyds ndd yygq bbq jjz xdxl jj qq wx dy wb bz ww " **

进行压缩变成如下表格:

字符该字符出现的次数
‘y’5
‘d’5
‘b’4
‘g’1
‘q’4
‘z’2
‘x’3
‘j’4
‘w’4
’ ’13

我们使用文本的方式储存这些 字符和出现的频率(注意:此博主比较懒输入,干脆整成一个文件)

input.txt:

y 5 d 5 g 1 q 4 z 2 x 3 j 4 w 4   13 

在这里插入图片描述

那问题来了 哈夫曼编码树? 这些只是从文件读取到内存里整成了一个顺序表, 而已

我们使用C I/O的函数 来读取 文件 .

回过神来!

能看得出来这些是一体的 所以ndd(你懂的),我们应该定义 全新的数据类型 : Huffman_Code

哈夫曼编码树数据域定义

 struct HuffmanCode{
 	char Val;//数据
    int weight;//频率
 }

定义完 先实现读取字符和频率

既然是顺序表 那还得用 统计 input.txt 文件的数据和频率多少个元素


const char* FileName = "input.txt";
const char* OpenMode = "r";
//读取的格式: 数据 空格 权值 空格
const  char* readFormat = "%c %d ";

//统计文件中的数据和频率的个数并且通过参数修改
bool  getSize(int& size) {

	FILE* ReadStream = nullptr;

	const	errno_t  openState = fopen_s(&ReadStream, FileName, OpenMode);
	bool ret = openState == 0;

	if (ret) {
		int i = 0;

		char ch = getc(ReadStream);
		ret = ch != EOF;
		if (ret) {

			ungetc(ch, ReadStream);
			HuffmanCodeValue value{};
			int ReadNum = 0;
			char read[alignof(HuffmanCodeValue) +2];

		
			//&value.value, sizeof(value.value), &space, sizeof(space), &value.weight, sizeof(value.weight)
			while (!feof(ReadStream)) {

				ReadNum = fscanf_s(ReadStream, readFormat, &value.value, sizeof(value.value), &value.weight, sizeof(value.weight));
				++i;
				
			}
			size = i;
		}
		else {

			cerr << "错误:" << FileName << "里文件为空" << endl;
		}
	

		fclose(ReadStream);
		ReadStream = nullptr;

	
	}
	else {

		char error[1024]{};
		strerror_s(error, errno);
		cerr << "错误:" << error << endl;
	}

	return ret;
}

分配好内存 之后 读取文件中的数据


//获取文件 哈夫曼编码 以及编码的权值
void loadValue(HuffmanCodeValue* value, const int &size) {

	if (size!=0){


		FILE* ReadStream = nullptr;

		const errno_t  openState = fopen_s(&ReadStream, FileName, OpenMode);
		bool ret = openState == 0;

		if (ret) {
			
			auto First = 0;
			int ReadNum = 0;
			char read[alignof(HuffmanCodeValue)+ 1];
			
			while (First != size && !feof(ReadStream)) {

				ReadNum = fscanf_s(ReadStream, readFormat, &value[First].value, sizeof(value[First].value), &value[First].weight, sizeof(value[First].weight));
			

				++First;
			}

			fclose(ReadStream);
			//free(ReadStream);
			ReadStream = nullptr;
		}

	}
}

读取完毕后 ,是时候 该设计一些数据结构了(也是,最骚脑的时刻)

哈夫曼编码树的定义

//哈夫曼编码树节点
struct HuffmanCodeTreeNode{
	HuffmanCode value;//数据
	HuffmanCodeTreeNode* Parent;//父节点
	HuffmanCodeTreeNode* LeftChild;//左子节点
	HuffmanCodeTreeNode* RightChild;//右子节点
};
//哈夫曼编码树
struct HuffmanCodeTree {
	HuffmanCodeTreeNode* root;//根节点
};

你以为到这里就结束了吗 …

那你就有点小瞧了哈夫曼编码树 还得按照优先级的频率来的

所以 还得吧写好的优先级队列搬出来

#ifndef __PriorityQueue_H__
#define __PriorityQueue_H__
#include"HuffmanTree.h"

using Element = HuffmanCodeTreeNode*;
using  PriorityQueueNode = struct _PriorityQueueNode;

using  PriorityCompare = bool (*)(const int &, const int &);

using PriorityQueueAuxiliary = struct _PriorityQueueAuxiliary;

using  PriorityQueue = struct _PriorityQueue;

struct _PriorityQueueNode {
	int Priority;
	Element value;
	PriorityQueueNode* next;
};

struct  _PriorityQueueAuxiliary {

	PriorityQueueNode* froot;
	PriorityQueueNode* back;
};

struct _PriorityQueue {
	PriorityCompare Compare;
	size_t size;
	PriorityQueueAuxiliary Auxiliary;
};

const size_t MaxSize = 1024;

void initPriorityQueue(PriorityQueue& priorityQueue, PriorityCompare c);
void PushPriorityQueue(PriorityQueue& priorityQueue,const Element& value);
bool fullPriorityQueue(const PriorityQueue& priorityQueue);
bool emptyPriorityQueue(const PriorityQueue& priorityQueue);
Element& PriorityQueueFroot(PriorityQueue& priorityQueue);// 禁止
//删除优先级队列 Element& value 设置到 value 里
void PopPriorityQueue(PriorityQueue& priorityQueue, Element& value);
void setCompare(PriorityQueue& priorityQueue, PriorityCompare Compare);
const size_t& PriorityQueueSize(PriorityQueue& priorityQueue);
void destroyPriorityQueue(PriorityQueue& priorityQueue);

#endif

PriorityQueue.cpp

#include"PriorityQueue.h"
#include<stdexcept>
using namespace std;


using Node = PriorityQueueNode;
const size_t zero = 0;

//创建优先级队列元素
Node* CreatePriorityQueueNode(const Element& value, Node* nullPtr = nullptr) {
	Node* node = new Node{ value->value.weight,value,nullPtr };

	return node;
}

void initPriorityQueue(PriorityQueue& priorityQueue, PriorityCompare c) {
	
	priorityQueue.Auxiliary = { nullptr,nullptr };
	priorityQueue.size = zero;
	priorityQueue.Compare = c;
}

bool fullPriorityQueue(const PriorityQueue& priorityQueue) {

	return priorityQueue.size == MaxSize;
}

bool emptyPriorityQueue(const PriorityQueue& priorityQueue) {

	return priorityQueue.size == zero;
}

void GetPriorityNode(Node*&, PriorityCompare&);

Element& PriorityQueueFroot(PriorityQueue& priorityQueue)
{
	if (emptyPriorityQueue(priorityQueue)) {
		destroyPriorityQueue(priorityQueue);
		terminate();
	}
	return priorityQueue.Auxiliary.froot->value;
}


void Link(Node*& node, Node* NewNode) {
	if (node) {
		node->next = NewNode;
	}
	node = NewNode;
}


const size_t& PriorityQueueSize(PriorityQueue& priorityQueue) {
	return priorityQueue.size;
}

void PushPriorityQueue(PriorityQueue& priorityQueue, const Element& value) {

	const bool iSfront = priorityQueue.size == zero;

	if (fullPriorityQueue(priorityQueue)) {
		destroyPriorityQueue(priorityQueue);
		terminate();
	}
	auto&& newNode = CreatePriorityQueueNode(value);

	auto& Froot = priorityQueue.Auxiliary.froot;
	auto& back = priorityQueue.Auxiliary.back;

	if (!iSfront) {
		Link(newNode->next ,Froot);//小的 调整
		Froot = newNode;
	
	}else{
		Link(back, newNode);
		Froot = back;	
	}
	
	++priorityQueue.size;
}


void GetPriorityNode(Node*& froot, PriorityCompare& Compare) {

	Node** node = &froot;
	Node* last = (froot);
	if (last) {


		Node* current = last->next;
		while (current) {
			if (Compare(current->Priority, (*node)->Priority)) {
				node = &(last->next);
			}
			last = current;
			current = current->next;
		}

		froot = *node;
	}
}


void setCompare(PriorityQueue& priorityQueue, PriorityCompare Compare) {

	priorityQueue.Compare = Compare;
}

void PopPriorityQueue(PriorityQueue& priorityQueue, Element& value) {
	if (emptyPriorityQueue(priorityQueue)) {

		destroyPriorityQueue(priorityQueue);
		terminate();

	}
	size_t& size = priorityQueue.size;


	Node** prev = NULL, * prev_node = NULL;

	Node* last = NULL, * tmp = NULL;
	
	prev = &(priorityQueue.Auxiliary.froot);
	
	last = priorityQueue.Auxiliary.froot;
	if (!last){
		--size;
	}
	else {

		tmp = last->next;
		while (tmp) {
			if (priorityQueue.Compare(tmp->Priority, (*prev)->Priority)) {

				prev = &(last->next);
				prev_node = last;
			}
			last = tmp;
			tmp = tmp->next;
		}

		value = (*prev)->value;
		auto DeleteNode = *prev;
		*prev = (*prev)->next;

	    delete DeleteNode;
		DeleteNode = nullptr;

		--size;
	}
	
	if (size == zero) {
		 (priorityQueue.Auxiliary.back) = nullptr;
	}

	if (prev_node && prev_node->next == NULL) {
		(priorityQueue.Auxiliary.back = prev_node);
	}
}

void destroyPriorityQueue(PriorityQueue& priorityQueue) {
	PriorityQueueAuxiliary& Auxiliary = priorityQueue.Auxiliary;
	Node*& Firsh = Auxiliary.froot;

	Node*& deleteNode = Firsh;
	size_t& size = priorityQueue.size;

	while (Firsh) {

		Node* next = Firsh->next;
		delete deleteNode;
		deleteNode = next;
	}

	priorityQueue = {};

}

插入小调整
=1670589638549)(assets/1670579952844.png)]
在这里插入图片描述

按照比较函数 经过比较函数来达到出队的目的

HuffmanTree.cpp

#include "HuffmanTree.h"
#include"PriorityQueue.h"
#include<iostream>
using std::cout;
using std::endl;

bool  priorityCompare(const int& Left, const int& Right){
    return Left < Right;
}

构建哈夫曼编码树

void build_HuffmanCodeTree(HuffmanCodeTree& tree, HuffmanCodeValue* value, size_t Size) {

	PriorityQueue priorityQueue;
	initPriorityQueue(priorityQueue, priorityCompare);


	HuffmanCodeTreeNode* newNode = nullptr;


	for (size_t i = 0; i < Size; i++) {
		newNode = new HuffmanCodeTreeNode{};
		newNode->value = value[i];
		PushPriorityQueue(priorityQueue, newNode);
	}

	HuffmanCodeTreeNode* Node1 = nullptr;
	HuffmanCodeTreeNode* Node2 = nullptr;


	int	i = 0;
	do {
	
		if (!emptyPriorityQueue(priorityQueue)) {
			PopPriorityQueue(priorityQueue, Node1);

			if (OutputISspace(Node1->value.value) == "空格")	{
				cout << "第"<<++i<<"次优先级队列 出队数据为:" << OutputISspace(Node1->value.value) << " 权值:" << Node1->value.weight << endl << endl;
			}
			else {
				cout << "第" << ++i << "次优先级队列 出队数据为:" << (Node1->value.value) << " 权值:" << Node1->value.weight << endl << endl;
			}
		}
		else {
			break;
		}

		if (!emptyPriorityQueue(priorityQueue)) {

			newNode = new HuffmanCodeTreeNode();
			PopPriorityQueue(priorityQueue, Node2);
			if (OutputISspace(Node2->value.value) == "空格") {
				cout << "第" << ++i << "次优先级队列 出队数据为:"<<OutputISspace(Node2->value.value) << " 权值:" << Node2->value.weight << endl << endl;
			}
			else {
				cout << "第" << ++i << "次优先级队列 出队数据为:"<<(Node2->value.value) << " 权值:" << Node2->value.weight << endl << endl;
			}

			newNode->LeftChild = Node1;
			Node1->Parent = newNode;
			newNode->RightChild = Node2;
			Node2->Parent = newNode;
			newNode->value.value = Space;

			newNode->value.weight = Node1->value.weight + Node2->value.weight;
			cout << "合并新结点 优先级队列 入队数据为:" << OutputISspace(newNode->value.value) << " 权值:" << newNode->value.weight << endl << endl;
			PushPriorityQueue(priorityQueue, newNode);
		}
		else {
			tree.root = Node1;
			break;
		}



	} while (true);

	destroyPriorityQueue(priorityQueue);
}

合并成新的树节点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

合并的结果
在这里插入图片描述

哈夫曼编码树算法实现

算法声明

bool  priorityCompare(const int& Left, const int& Right);
//构建哈夫曼编码树
void build_HuffmanCodeTree(HuffmanCodeTree& tree, HuffmanCodeValue* value, size_t Size);
//前序遍历
void FirstOrderRecursiveTraversal(HuffmanCodeTreeNode*& Root);
//销毁哈夫曼编码树
void DestroyHuffmanCodeTree(HuffmanCodeTreeNode*& root);

算法实现

#include "HuffmanTree.h"
#include"PriorityQueue.h"
#include<iostream>
using std::cout;
using std::endl;

bool  priorityCompare(const int& Left, const int& Right){
    return Left < Right;
}

void build_HuffmanCodeTree(HuffmanCodeTree& tree, HuffmanCodeValue* value, size_t Size) {

	PriorityQueue priorityQueue;
	initPriorityQueue(priorityQueue, priorityCompare);


	HuffmanCodeTreeNode* newNode = nullptr;


	for (size_t i = 0; i < Size; i++) {
		newNode = new HuffmanCodeTreeNode{};
		newNode->value = value[i];
		PushPriorityQueue(priorityQueue, newNode);
	}

	HuffmanCodeTreeNode* Node1 = nullptr;
	HuffmanCodeTreeNode* Node2 = nullptr;


	int	i = 0;
	do {
	
		if (!emptyPriorityQueue(priorityQueue)) {
			PopPriorityQueue(priorityQueue, Node1);

			if (OutputISspace(Node1->value.value) == "空格")	{
				cout << "第"<<++i<<"次优先级队列 出队数据为:" << OutputISspace(Node1->value.value) << " 权值:" << Node1->value.weight << endl << endl;
			}
			else {
				cout << "第" << ++i << "次优先级队列 出队数据为:" << (Node1->value.value) << " 权值:" << Node1->value.weight << endl << endl;
			}
		}
		else {
			break;
		}

		if (!emptyPriorityQueue(priorityQueue)) {

			newNode = new HuffmanCodeTreeNode();
			PopPriorityQueue(priorityQueue, Node2);
			if (OutputISspace(Node2->value.value) == "空格") {
				cout << "第" << ++i << "次优先级队列 出队数据为:"<<OutputISspace(Node2->value.value) << " 权值:" << Node2->value.weight << endl << endl;
			}
			else {
				cout << "第" << ++i << "次优先级队列 出队数据为:"<<(Node2->value.value) << " 权值:" << Node2->value.weight << endl << endl;
			}

			newNode->LeftChild = Node1;
			Node1->Parent = newNode;
			newNode->RightChild = Node2;
			Node2->Parent = newNode;
			newNode->value.value = Space;

			newNode->value.weight = Node1->value.weight + Node2->value.weight;
			cout << "合并新结点 优先级队列 入队数据为:" << OutputISspace(newNode->value.value) << " 权值:" << newNode->value.weight << endl << endl;
			PushPriorityQueue(priorityQueue, newNode);
		}
		else {
			tree.root = Node1;
			break;
		}



	} while (true);

	destroyPriorityQueue(priorityQueue);
}

void FirstOrderRecursiveTraversal(HuffmanCodeTreeNode*& Root) {
	if (Root) {
		 
			cout << "- :" << (Root->value.value) << " -" << endl;
		

			//cout << "压缩数据为:" << (Root->value.value) << endl;
		
		FirstOrderRecursiveTraversal(Root->LeftChild);
		FirstOrderRecursiveTraversal(Root->RightChild);

	}
}

void DestroyHuffmanCodeTree(HuffmanCodeTreeNode*& root) {
	
	if (root) {

		DestroyHuffmanCodeTree(root->LeftChild);
		
		DestroyHuffmanCodeTree(root->RightChild);

		delete root;
		root = {};

	}
}

main函数

#include<iostream>
#include"HuffmanTree.h"
#include"PriorityQueue.h"

using namespace std;

const char* FileName = "input.txt";
const char* OpenMode = "r";
//读取的格式: 数据 空格 权值 空格
const  char* readFormat = "%c %d ";

//统计文件中的数据和频率的个数并且通过参数修改
bool  getSize(int& size) {

	FILE* ReadStream = nullptr;

	const	errno_t  openState = fopen_s(&ReadStream, FileName, OpenMode);
	bool ret = openState == 0;

	if (ret) {
		int i = 0;

		char ch = getc(ReadStream);
		ret = ch != EOF;
		if (ret) {

			ungetc(ch, ReadStream);
			HuffmanCodeValue value{};
			int ReadNum = 0;
			char read[alignof(HuffmanCodeValue) +2];

		
			//&value.value, sizeof(value.value), &space, sizeof(space), &value.weight, sizeof(value.weight)
			while (!feof(ReadStream)) {

				ReadNum = fscanf_s(ReadStream, readFormat, &value.value, sizeof(value.value), &value.weight, sizeof(value.weight));
				++i;
				
			}
			size = i;
		}
		else {

			cerr << "错误:" << FileName << "里文件为空" << endl;
		}
	

		fclose(ReadStream);
		ReadStream = nullptr;

	
	}
	else {

		char error[1024]{};
		strerror_s(error, errno);
		cerr << "错误:" << error << endl;
	}

	return ret;
}

//获取文件 哈夫曼编码 以及编码的权值
void loadValue(HuffmanCodeValue* value, const int &size) {

	if (size!=0){


		FILE* ReadStream = nullptr;

		const errno_t  openState = fopen_s(&ReadStream, FileName, OpenMode);
		bool ret = openState == 0;

		if (ret) {
			
			auto First = 0;
			int ReadNum = 0;
			char read[alignof(HuffmanCodeValue)+ 1];
			
			while (First != size && !feof(ReadStream)) {

				ReadNum = fscanf_s(ReadStream, readFormat, &value[First].value, sizeof(value[First].value), &value[First].weight, sizeof(value[First].weight));
			

				++First;
			}

			fclose(ReadStream);
			//free(ReadStream);
			ReadStream = nullptr;
		}

	}
}


int main(void) {
	
	HuffmanCodeValue* value;
	HuffmanCodeTree tree{};
	int size;
	if (getSize(size)){

		value = new  HuffmanCodeValue[size];
		loadValue(value, size);

		build_HuffmanCodeTree(tree, value, size);
		FirstOrderRecursiveTraversal(tree.root);
		delete [] value;
		DestroyHuffmanCodeTree(tree.root);
	}
	return 0;
}

output:

第1次优先级队列 出队数据为:g 权值:1

第2次优先级队列 出队数据为:z 权值:2

合并新结点 优先级队列 入队数据为:空格 权值:3

第3次优先级队列 出队数据为:空格 权值:3

第4次优先级队列 出队数据为:1 权值:3

合并新结点 优先级队列 入队数据为:空格 权值:6

第5次优先级队列 出队数据为:x 权值:3

第6次优先级队列 出队数据为:w 权值:4

合并新结点 优先级队列 入队数据为:空格 权值:7

第7次优先级队列 出队数据为:j 权值:4

第8次优先级队列 出队数据为:q 权值:4

合并新结点 优先级队列 入队数据为:空格 权值:8

第9次优先级队列 出队数据为:d 权值:5

第10次优先级队列 出队数据为:y 权值:5

合并新结点 优先级队列 入队数据为:空格 权值:10

第11次优先级队列 出队数据为:空格 权值:6

第12次优先级队列 出队数据为:空格 权值:7

合并新结点 优先级队列 入队数据为:空格 权值:13

第13次优先级队列 出队数据为:空格 权值:8

第14次优先级队列 出队数据为:空格 权值:10

合并新结点 优先级队列 入队数据为:空格 权值:18

第15次优先级队列 出队数据为:空格 权值:13

第16次优先级队列 出队数据为:空格 权值:18

合并新结点 优先级队列 入队数据为:空格 权值:31

第17次优先级队列 出队数据为:空格 权值:31

- :  -
- :  -
- :  -
- :  -
- :g -
- :z -
- :1 -
- :  -
- :x -
- :w -
- :  -
- :  -
- :j -
- :q -
- :  -
- :d -
- :y -

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

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

相关文章

C++中STL用法超详细总结(收藏级)

1 什么是STL&#xff1f; STL&#xff08;Standard Template Library&#xff09;&#xff0c;即标准模板库&#xff0c;是一个具有工业强度的&#xff0c;高效的C程序库。它被容纳于C标准程序库&#xff08;C Standard Library&#xff09;中&#xff0c;是ANSI/ISO C标准中最…

密码学(1)RSA与AES算法原理

什么是RSA 在1977年&#xff0c;Ron Rivest, Adi Shami和Leonard Adleman这三个人开发了一个新的算法&#xff0c;并用他们三个名字的首字母来命名这个算法&#xff0c;这个算法名叫RSA 非对称加密与对称加密 RSA算法采用的是非对称加密&#xff0c;假如我有你的公钥&#x…

从零到一手写一个小型RPC框架——介绍篇

RPC框架介绍 RPC框架是微服务的通信工具&#xff0c;其涉及到网络传输、服务注册、序列化、代理模式等等知识的学习与使用&#xff0c;是微服务的入门框架。 现有的比较知名的RPC框架有阿里巴巴开源的Dubbo&#xff0c;谷歌的开源RPC框架gRPC&#xff0c;甚至SpringCloud中所…

vue2笔记4(服务代理、插槽、vuex、路由)

vue脚手架 ## vue脚手架配置代理 vue在请求服务器的资源的时候&#xff0c;自身使用的是8080端口&#xff0c;如果服务器端口号是别的&#xff0c;这时候直接访问的话就会出现跨域的问题无法访问&#xff0c;就需要使用一个代理来访问服务器。vue配置脚手架的代理有两种方式。…

Unreal Engine学习

1&#xff0c;什么是组件&#xff1f; 继承于Uobject的为了给actor以及其他在场景中显示出来的类增加新的功能的一个东西 2&#xff0c;可以自己创建一个蓝图&#xff0c;然后将蓝图拖到场景中&#xff0c;也可以直接在c class中将蓝图拖到场景中 3&#xff0c;创建一个组件&…

vuex的新写法引入mapState省略$store.state

vuex的新写法&#xff1a; state简写&#xff08;映射&#xff09;&#xff1a;mapState state里都是状态&#xff0c;所以mapState在computed中使用&#xff1b;state映射也就是引入mapState&#xff0c;然后state可以简写$store.state.状态 > 状态&#xff1a;前面的$s…

多点Dmall冲刺港交所上市:前三季度营收11亿元,张文中为实控人

撰稿|汤汤 来源|贝多财经 日前&#xff0c;多点数智有限公司&#xff08;下称“多点Dmall”或“多点”&#xff09;向港交所递交招股书&#xff0c;准备在港交所主板上市&#xff0c;瑞信、招银国际为其联席保荐人。 据贝多财经了解&#xff0c;多点Dmall在境内的主要经营主体…

《Linux运维实战:MongoDB数据库全量逻辑备份恢复(方案二)》

一、备份与恢复方案 Mongodb中的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件。可以通过参数指定导出的数据项&#xff0c;也可以根据指定的条件导出数据&#xff0c;只支持导出集合(collection)&#xff0c;不支持导出库。 由于mongodb实例里面的数据类…

宠物网页作业HTML 大一作业HTML宠物网页作业 web期末大作业HTML 动物网页作业HTML HTML制作宠物网页作业css

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

区块链行业的一次“里程碑时刻”…

12月8日&#xff0c;由中国新闻社、中国新闻周刊主办的第十八届中国企业社会责任论坛成功举办&#xff0c;欧科云链入选“2022年度责任企业”&#xff0c;成为历届唯一获奖的区块链科技企业。 1999年1月&#xff0c;在瑞士达沃斯世界经济论坛上&#xff0c;联合国秘书长安南提出…

如何搞一个在线的Shape生成

Shape是Android中一个必不可少的资源&#xff0c;很多的背景&#xff0c;比如圆角&#xff0c;分割线、渐变等等效果&#xff0c;几乎都有它的影子存在&#xff0c;毕竟写起来简单便捷&#xff0c;使用起来也是简单便捷&#xff0c;又占用内存小&#xff0c;谁能不爱&#xff1…

【Python游戏】咱就说Python实现一个蔡徐坤大战篮球的小游戏,可还行? | 附带源码

前言 halo&#xff0c;包子们下午好 小编作为一个鸡你太美的忠实黑粉&#xff0c;怎么能不实行一个蔡徐坤大战篮球的小游戏呢 今天小编用Python给大家实现啦 今天不为别的&#xff0c;就是想督促大家学习 废话不多说&#xff0c;直接开整 相关文件 关注小编&#xff0c;私信…

GoDiagram.Winforms完全重写版-Crack

介绍GoDiagram 10 – 用于 .NET 项目的新图表库。 GoDiagram 10 是 GoDiagram 的完全重写&#xff0c;基于 GoJS API&#xff0c;具有相同的功能。这包括节点和链接的模板、数据绑定、JSON 模型数据格式、动画和许多其他功能。 在 C# 中为 .NET 构建图表 流程图 构建交互式流程…

安卓APP源码和设计报告——仿淘宝购物APP

2021—2022学年第二学期期末考试 《Android手机软件开发》实践考核 项目设计说明书 项目名称&#xff1a; 购物APP的设计与实现 专 业&#xff1a; 计算机科学与技术 学 号&#xff1a; 姓 名&#xff1a; 任课教师&#xff1a; 2022年6月12日 目 录 1.项目概述11 2…

磨金石教育摄影技能干货分享|优秀摄影欣赏—足球经典名画

世界杯正在如火如荼的进行&#xff0c;相信通过本次世界杯先进的转播技术&#xff0c;又会诞生一大批新的足球迷。而随着拍摄技术的进步&#xff0c;足球场上的许多精彩瞬间也被更清晰的抓拍下来。 1、c罗的惊讶 这张照片相信看过本届世界杯的朋友都不陌生&#xff0c;c罗做出…

[效率工具] Git下对敏感文件/内容的处理

&#x1f341;简介 &#x1f517; 相关资料 : 一文玩转Git 有时候我们提交代码到GitHub/Giglab平台, 发现一不小心把带有账号密码以及服务器地址的代码等敏感信息提交到公共平台,对于这种情况我们应该使用一些方案进行规避。下面就讨论下这些方案&#xff01; 方法一: 配置文件…

『SnowFlake』雪花算法的详解及时间回拨解决方案

&#x1f4e3;读完这篇文章里你能收获到 图文形式为你讲解原生雪花算法的特征及原理了解时间回拨的概念以及可能引起发此现象的操作掌握时间回拨的解决方案—基于时钟序列的雪花算法关于雪花算法的常见问题解答 文章目录一、原生的雪花算法1. 简介2. 特征3. 原理3.1 格式&…

什么软件可以去除照片水印?这3种方法可以帮你轻松搞定

大家有过这样的烦恼吗&#xff1f;在网上看到一张喜欢的图片&#xff0c;想要将它保存下来做壁纸&#xff0c;但是却发现图片里面有个大大的水印&#xff0c;十分影响效果。或者是在网上看到一张喜欢的头像&#xff0c;里面也有着一个大大的水印&#xff0c;我们该放弃这张图片…

【能源物联网】物联网体系结构与建筑能源管理系统的相关性分析

摘要&#xff1a; 在能源形势紧张的大趋势下&#xff0c;高能耗的大型公共建筑能源管理系统的建设逐渐受到重视&#xff0c;以物联网技术及基础的建筑能源管理平台可以提供即时、准确、高效的能源管理策略。系统阐述了结合物联网技术的建筑能源管理构建方法&#xff0c;对物联…

低代码助力制造型企业——工时管理系统

生产管理是制造企业的核心职能之一,工时管理是生产管理的重要方法和手段&#xff0c;可以帮助更好的掌控交货期&#xff0c;控制成本&#xff0c;更准确的安排生产计划。在当前激烈竞争的市场环境下&#xff0c;企业必须以现代化的理念结合不断改进的管理方法才能及时抓住发展机…