当前位置: 首页 > news >正文

【数据结构-树】哈夫曼树

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
img

  • 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • 檀越剑指大厂系列:全面总结 java 核心技术点,如集合,jvm,并发编程 redis,kafka,Spring,微服务,Netty 等
    • 常用开发工具系列:罗列常用的开发工具,如 IDEA,Mac,Alfred,electerm,Git,typora,apifox 等
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

    • 一.哈夫曼算法
      • 1.什么是编码?
      • 2.编码传输规则
      • 3.Huffman 编码
    • 二.哈夫曼树
      • 1.什么 Huffman 树?
      • 2.哈夫曼树特点
      • 3.节点总数证明
      • 4.Huffman 树特点
    • 三.常见方法
      • 1.内部 Node 节点
      • 2.构造方法
      • 3.编码
      • 4.解码
      • 5.完整代码
    • 四.练习题
      • 1.连接棒材的最低费用-力扣 1167 题

一.哈夫曼算法

1.什么是编码?

简单说就是建立【字符】到【数字】的对应关系,如下面大家熟知的 ASC II 编码表,例如,可以查表得知字符【a】对应的数字是十六进制数【0x61】

\000102030405060708090a0b0c0d0e0f
0000000102030405060708090a0b0c0d0e0f
0010101112131415161718191a1b1c1d1e1f
002020!"#$%&()*+,-./
00300123456789:;<=>?
0040@ABCDEFGHIJKLMNO
0050PQRSTUVWXYZ[\]^_
0060`abcdefghijklmno
0070pqrstuvwxyz{|}~7f

注:一些直接以十六进制数字标识的是那些不可打印字符

2.编码传输规则

传输时的编码

  • java 中每个 char 对应的数字会占用固定长度 2 个字节
  • 如果在传输中仍采用上述规则,传递 abbccccccc 这 10 个字符
    • 实际的字节为 0061006200620063006300630063006300630063(16 进制表示)
    • 总共 20 个字节,不经济

现在希望找到一种最节省字节的传输方式,怎么办?

假设传输的字符中只包含 a,b,c 这 3 个字符,有同学重新设计一张二进制编码表,见下图

  • 0 表示 a
  • 1 表示 b
  • 10 表示 c

现在还是传递 abbccccccc 这 10 个字符

  • 实际的字节为 01110101010101010 (二进制表示)
  • 总共需要 17 bits,也就是 2 个字节多一点,行不行?

不行,因为解码会出现问题,因为 10 会被错误的解码成 ba,而不是 c

  • 解码后结果为 abbbababababababa,是错误的

怎么解决?必须保证编码后的二进制数字,要能区分它们的前缀(prefix-free)

用满二叉树结构编码,可以确保前缀不重复

image-20230616094945068

  • 向左走 0,向右走 1
  • 走到叶子字符,累计起来的 0 和 1 就是该字符的二进制编码

再来试一遍

  • a 的编码 0
  • b 的编码 10
  • c 的编码 11

现在还是传递 abbccccccc 这 10 个字符

  • 实际的字节为 0101011111111111111(二进制表示)
  • 总共需要 19 bits,也是 2 个字节多一点,并且解码没有问题了,行不行?

这回解码没问题了,但并非最少字节,因为 c 的出现频率高(7 次)a 的出现频率低(1 次),因此出现频率高的字符编码成短数字更经济

3.Huffman 编码

考察下面的树

image-20230616095129461

  • 00 表示 a
  • 01 表示 b
  • 1 表示 c

现在还是传递 abbccccccc 这 10 个字符

  • 实际的字节为 000101 1111111 (二进制表示)
  • 总共需要 13 bits,这棵树就称之为 Huffman 树
  • 根据 Huffman 树对字符和数字进行编解码,就是 Huffman 编解码

二.哈夫曼树

1.什么 Huffman 树?

哈夫曼树,英文名 huffman tree,它是一种的叶子节点带有权重的特殊二叉树,也叫最优二叉树。

哈夫曼(Huffman)编码是上个世纪五十年代由哈夫曼教授研制开发的,它借助了数据结构当中的树型结构,在哈夫曼算法的支持下构造出一棵最优二叉树,我们把这类树命名为哈夫曼树。

哈夫曼树是带权路径长度最短的树,权值较大的节点离根较近。

2.哈夫曼树特点

哈夫曼树的特点:

  • 没有度为1的节点(每个非叶子节点都是由两个最小值的节点构成)

  • n 个叶子节点的哈夫曼树总共有2n-1个节点;

  • 哈夫曼树的任意非叶节点的左右子树交换后仍是哈夫曼树

  • 对同一组权值{w1,w2,…},存在不同构的两个哈夫曼树,但是它们的总权值相等。

  • 形成了这样的一颗哈夫曼树,这也是二叉树的前序

3.节点总数证明

证明哈夫曼树中有 n 个叶子节点的树总共有 2n-1 个节点可以使用数学归纳法。以下是证明的步骤:

步骤 1:基础情况
当 n=1 时,只有一个叶子节点,因此整棵哈夫曼树只有一个节点。这是一个基础情况。

步骤 2:归纳假设
假设对于某个正整数 k,当哈夫曼树有 k 个叶子节点时,它总共有 2k-1 个节点。

步骤 3:归纳证明
现在,考虑有 k+1 个叶子节点的情况。我们可以将这个问题分成两个部分:

部分 1: 从 k 个叶子节点构建一个哈夫曼树,根据归纳假设,这个树有 2k-1 个节点。

部分 2: 现在,我们添加一个额外的叶子节点,构建一个新的哈夫曼树。在这个新树中,我们需要添加一个新的内部节点,作为新叶子节点和部分 1 中的树的根节点的父节点。这个新树总共有 2k 个叶子节点和 1 个额外的内部节点,所以共有 2k+1 个节点。

现在,将部分 1 和部分 2 合并在一起,我们得到了有 k+1 个叶子节点的哈夫曼树,总共有(2k-1) + (2k+1) = 2k-1 + 2k+1 = 2(k-1+2) = 2k+1-1 个节点。

这证明了对于 k+1 个叶子节点的情况,有 2k+1-1 个节点,即当 n=k+1 时,也成立。

由于基础情况成立,并且我们已经证明了当 n=k+1 时成立,所以根据数学归纳法,对于所有正整数 n,有 n 个叶子节点的哈夫曼树总共有 2n-1 个节点。

4.Huffman 树特点

哈夫曼树(Huffman Tree)是一种用于数据压缩的树形数据结构,它具有以下几个特点:

  1. 最优编码:哈夫曼树被设计用来实现最优的数据压缩编码,这意味着它可以生成具有最小平均编码长度的编码方案,以便在数据传输或存储时能够节省空间。

  2. 基于频率:哈夫曼树的构建是基于数据中各个字符(或符号)的出现频率来进行的。频率高的字符被赋予较短的编码,而频率低的字符被赋予较长的编码。

  3. 唯一性:对于给定的数据集,存在唯一的哈夫曼树。这意味着如果两个人使用相同的数据集和相同的构建规则来创建哈夫曼树,它们将得到相同的树结构和编码。

  4. 前缀编码:哈夫曼编码是一种前缀编码,意味着没有一个字符的编码是另一个字符编码的前缀。这个特性确保在解码时不会产生歧义。

  5. 树形结构:哈夫曼树是一种二叉树,它由内部节点和叶子节点组成。叶子节点对应于数据集中的字符,而内部节点是用于构建编码的辅助节点。

  6. 压缩率:哈夫曼编码通常能够实现较高的压缩率,尤其是对于具有不同频率分布的数据集。频率高的字符使用较短的编码,从而实现更好的压缩效果。

  7. 动态性:哈夫曼编码可以动态地根据数据集的特性进行调整,以适应不同的数据。这使得它在各种应用中都具有灵活性。

总之,哈夫曼树是一种用于数据压缩的有效工具,其特点包括最优编码、基于频率、唯一性、前缀编码、树形结构、高压缩率和动态性。通过合理构建哈夫曼树,可以实现高效的数据压缩和解压缩操作。

三.常见方法

1.内部 Node 节点

/*** Node代表字符节点*/
static class Node {/*** 字符*/Character ch;/*** 频次*/int freq;/*** 左子节点*/Node left;/*** 右子节点*/Node right;/*** 编码*/String code;public Node(Character ch) {this.ch = ch;}public Node(int freq, Node left, Node right) {this.freq = freq;this.left = left;this.right = right;}int freq() {return freq;}boolean isLeaf() {return left == null;}@Overridepublic String toString() {return "Node{" + "ch=" + ch + ", freq=" + freq + '}';}
}

2.构造方法

public HuffmanTree(String str) {this.str = str;// 功能1:统计字符的频率char[] chars = str.toCharArray();for (char c : chars) {Node node = map.computeIfAbsent(c, Node::new);node.freq++;}// 功能2: 构造树PriorityQueue<Node> queue = new PriorityQueue<>(Comparator.comparingInt(Node::freq));queue.addAll(map.values());while (queue.size() >= 2) {Node x = queue.poll();Node y = queue.poll();int freq = x.freq + y.freq;queue.offer(new Node(freq, x, y));}root = queue.poll();// 功能3:计算每个字符的编码,int sum = dfs(root, new StringBuilder());for (Node node : map.values()) {System.out.println(node + " " + node.code);}// 功能4:字符串编码后占用 bitsSystem.out.println("总共会占用 bits:" + sum);
}private int dfs(Node node, StringBuilder code) {int sum = 0;if (node.isLeaf()) {node.code = code.toString();sum = node.freq * code.length();} else {sum += dfs(node.left, code.append("0"));sum += dfs(node.right, code.append("1"));}if (code.length() > 0) {code.deleteCharAt(code.length() - 1);}return sum;}

3.编码

public String encode() {//abbcccccccchar[] chars = str.toCharArray();StringBuilder sb = new StringBuilder();for (char c : chars) {sb.append(map.get(c).code);}return sb.toString();
}

4.解码

public String decode(String str) {/*从根节点,寻找数字对应的字符数字是 0 向左走数字是 1 向右走如果没走到头,每走一步数字的索引 i++走到头就可以找到解码字符,再将 node 重置为根节点a 00b 10c 1i0   0   0   1   0   1   1   1   1   1   1   1   1*/char[] chars = str.toCharArray();int i = 0;StringBuilder sb = new StringBuilder();Node node = root;//             i = 13  node=root// 0001011111111while (i < chars.length) {if (!node.isLeaf()) { // 非叶子if (chars[i] == '0') { // 向左走node = node.left;} else if (chars[i] == '1') { // 向右走node = node.right;}i++;}if (node.isLeaf()) {sb.append(node.ch);node = root;}}return sb.toString();
}

5.完整代码

/*** Huffman 树的构建过程* 1. 将统计了出现频率的字符,放入优先级队列* 2. 每次出队两个频次最低的元素,给它俩找个爹* 3. 把爹重新放入队列,重复 2~3* 4. 当队列只剩一个元素时,Huffman 树构建完成** @author : qinyingjie* @date : 2023/9/26*/
public class HuffmanTree {/*** Node代表字符节点*/static class Node {/*** 字符*/Character ch;/*** 频次*/int freq;/*** 左子节点*/Node left;/*** 右子节点*/Node right;/*** 编码*/String code;public Node(Character ch) {this.ch = ch;}public Node(int freq, Node left, Node right) {this.freq = freq;this.left = left;this.right = right;}int freq() {return freq;}boolean isLeaf() {return left == null;}@Overridepublic String toString() {return "Node{" + "ch=" + ch + ", freq=" + freq + '}';}}String str;/*** 统计字符数量,key是字符,value是节点*/Map<Character, Node> map = new HashMap<>();/*** 根节点*/Node root;public HuffmanTree(String str) {this.str = str;// 功能1:统计字符的频率char[] chars = str.toCharArray();for (char c : chars) {Node node = map.computeIfAbsent(c, Node::new);node.freq++;}// 功能2: 构造树PriorityQueue<Node> queue = new PriorityQueue<>(Comparator.comparingInt(Node::freq));queue.addAll(map.values());while (queue.size() >= 2) {Node x = queue.poll();Node y = queue.poll();int freq = x.freq + y.freq;queue.offer(new Node(freq, x, y));}root = queue.poll();// 功能3:计算每个字符的编码,int sum = dfs(root, new StringBuilder());for (Node node : map.values()) {System.out.println(node + " " + node.code);}// 功能4:字符串编码后占用 bitsSystem.out.println("总共会占用 bits:" + sum);}private int dfs(Node node, StringBuilder code) {int sum = 0;if (node.isLeaf()) {node.code = code.toString();sum = node.freq * code.length();} else {sum += dfs(node.left, code.append("0"));sum += dfs(node.right, code.append("1"));}if (code.length() > 0) {code.deleteCharAt(code.length() - 1);}return sum;}// 编码public String encode() {//abbcccccccchar[] chars = str.toCharArray();StringBuilder sb = new StringBuilder();for (char c : chars) {sb.append(map.get(c).code);}return sb.toString();}// 解码public String decode(String str) {/*从根节点,寻找数字对应的字符数字是 0 向左走数字是 1 向右走如果没走到头,每走一步数字的索引 i++走到头就可以找到解码字符,再将 node 重置为根节点a 00b 10c 1i0   0   0   1   0   1   1   1   1   1   1   1   1*/char[] chars = str.toCharArray();int i = 0;StringBuilder sb = new StringBuilder();Node node = root;//             i = 13  node=root// 0001011111111while (i < chars.length) {if (!node.isLeaf()) { // 非叶子if (chars[i] == '0') { // 向左走node = node.left;} else if (chars[i] == '1') { // 向右走node = node.right;}i++;}if (node.isLeaf()) {sb.append(node.ch);node = root;}}return sb.toString();}public static void main(String[] args) {HuffmanTree tree = new HuffmanTree("abbccccccc");String encoded = tree.encode();System.out.println(encoded);System.out.println(tree.decode(encoded));}
}

四.练习题

1.连接棒材的最低费用-力扣 1167 题

题目编号题目标题算法思路
1167(Plus 题目)连接棒材的最低费用Huffman 树、贪心

为了装修新房,你需要加工一些长度为正整数的棒材 sticks。

如果要将长度分别为 X 和 Y 的两根棒材连接在一起,你需要支付 X + Y 的费用。

由于施工需要,你必须将所有棒材连接成一根。

返回你把所有棒材 sticks 连成一根所需要的最低费用。注意你可以任意选择棒材连接的顺序。

示例 1:
输入:sticks = [2,4,3]
输出:14
解释:先将 2 和 3 连接成 5,花费 5;再将 5 和 4 连接成 9;总花费为 14。
示例 2:
输入:sticks = [1,8,3,5]
输出:30
提示:
1 <= sticks.length <= 10^4
1 <= sticks[i] <= 10^4

题解

/*** <h3>连接棒材的最低费用</h3>* <p>为了装修新房,你需要加工一些长度为正整数的棒材。如果要将长度分别为 X 和 Y 的两根棒材连接在一起,你需要支付 X + Y 的费用。 返回讲所有棒材连成一根所需要的最低费用。</p>*/
public class Leetcode1167 {/*举例 棒材为 [1,8,3,5]如果以如下顺序连接(非最优)- 1+8=9- 9+3=12- 12+5=17总费用为 9+12+17=38如果以如下顺序连接(最优)- 1+3=4- 4+5=9- 8+9=17总费用为 4+9+17=30*/int connectSticks(int[] sticks) {PriorityQueue<Integer> queue = new PriorityQueue<>();for (int stick : sticks) {queue.offer(stick);}int sum = 0;while (queue.size() >= 2) {Integer x = queue.poll();Integer y = queue.poll();int c = x + y;sum += c;queue.offer(c);}return sum;}public static void main(String[] args) {Leetcode1167 leetcode = new Leetcode1167();System.out.println(leetcode.connectSticks(new int[]{1, 8, 3, 5})); // 30System.out.println(leetcode.connectSticks(new int[]{2, 4, 3})); // 14}
}

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img

相关文章:

【数据结构-树】哈夫曼树

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…...

HarmonyOS 4.0 实况窗上线!支付宝实现医疗场景智能提醒

本文转载自支付宝体验科技&#xff0c;作者是蚂蚁集团客户端工程师博欢&#xff0c;介绍了支付宝如何基于 HarmonyOS 4.0 实况窗实现医疗场景履约智能提醒。 1.话题背景 8 月 4 日&#xff0c;华为在 HDC&#xff08;华为 2023 开发者大会&#xff09;上推出了新版本操作系统…...

【响应式布局】

响应式布局 1 什么是响应式布局2 响应式布局的5种实现方案2.1 百分比布局2.2 媒体查询布局2.3 rem响应式布局2.4 vw / vh响应式布局2.5 flex弹性布局 1 什么是响应式布局 响应式布局就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。这个概念是为解决移动互…...

Spring面试题23:Spring支持哪些事务管理类型?Spring框架的事务管理有哪些优点?你更倾向用哪种事务管理类型?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Spring支持哪些事务管理类型? Spring 支持以下几种事务管理类型: 编程式事务管理:通过在代码中显式地使用事务管理 API(如 TransactionTempla…...

Leetcode—— LCR 122. 路径加密

LCR 122. 路径加密 假定一段路径记作字符串 path&#xff0c;其中以 "." 作为分隔符。现需将路径加密&#xff0c;加密方法为将 path 中的分隔符替换为空格 " "&#xff0c;请返回加密后的字符串。 示例 1&#xff1a; 输入&#xff1a;path "a.ae…...

缓冲区溢出漏洞分析

一、实验目的 熟悉软件安全需求分析方法&#xff0c;掌握软件安全分析技术。 二、实验软硬件要求 1、操作系统&#xff1a;windows 7/8/10等 2、开发环境&#xff1a;VS 6.0&#xff08;C&#xff09;、OllyDbg 三、实验预习 《软件安全技术》教材第3章 四、实验内容&#…...

【高阶数据结构】红黑树(C++实现)

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;C进阶 ⭐代码仓库&#xff1a;C进阶 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们的支持是我…...

算力百川汇蓝海,商海荡漾绘宏图

算力百川汇蓝海 01 新兴技术呼唤算力 崭新时代逐浪前&#xff0c;科技浪潮涌向天。 人工智能、数字孪生、元宇宙等新兴技术的迅速发展&#xff0c;引爆全球算力需求的规模式增长。尤其&#xff0c;以ChatGPT为代表的人工智能技术发展&#xff0c;引发了全球算力需求的进一步增长…...

ORACLE 内存结构之系统全局区(SGA)

每个 Oracle 数据库实例都会在内存中分配一个很大的内存结构&#xff0c; 称为系统全局区(System Global Area), 这是一个大型的共享内存结构,每个Oracle进程都会访问它。 在Linux/Unix操作系统上,SGA是一个物理实体&#xff0c;使用操作系统命令能“看到它”。 它被操作系…...

主要文档分享网站一览

136****0621的全部文档-第1页-原创力文档 目前能提供上传文档并付费的网站&#xff1a; 1、得利文库 www.deliwenku.com 先说我自已的吧&#xff01;见笑了 2、百度文库 wenku.baidu.com 这个算头部了、有流量倾斜、但资源多、用户现在上传的大部份为重复的&#xff0c;…...

CPU访问一个虚拟地址的整体流程

一、虚拟地址转换成物理地址 涉及到的部件&#xff1a; MMU&#xff1a;虚拟地址—MMU—>物理地址。MMU会控制整个流程&#xff08;查快表、查慢表等等&#xff09;TLB快表&#xff1a;组号&#xff08;若为组相联TLB&#xff09;、TLB标记、有效位、页框号页表&#xff08…...

UE5 虚幻引擎 如何使用构造脚本(Construction Script)? 构造脚本的奥秘!

目录 1 构造脚本&#xff08;Construction Script&#xff09;1.1 介绍1.2 案例1&#xff1a;利用样条组件程序化生成树木1.2 案例2&#xff1a;利用样条组件和样条网格体组件程序化生成道路 1 构造脚本&#xff08;Construction Script&#xff09; 1.1 介绍 问题&#xff1a…...

Mysql高级——数据库设计规范(2)

8. ER模型 ER 模型中有三个要素&#xff0c;分别是实体、属性和关系。 实体&#xff0c;可以看做是数据对象&#xff0c;往往对应于现实生活中的真实存在的个体。在 ER 模型中&#xff0c;用矩形来表示。实体分为两类&#xff0c;分别是强实体和弱实体。强实体是指不依赖于其…...

c++-string

文章目录 前言一、STL库介绍二、标准库中的string类1、string类介绍2、string类使用3.1 string类的构造函数3.2 string类对象的容量操作3.3 string类对象的遍历操作3.4 string类对象的访问操作3.5 string类对象的修改操作3.6 string类对象的字符串操作 三、模拟实现string类四、…...

KNN-K近邻算法(K-Nearest Neighbors)

k近邻算法的特点 思想极度简单应用数学知识少&#xff08;近乎为零&#xff09;效果好(缺点&#xff1f;)可以解释机器学习算法使用过程中的很多细节问题更完整的刻画机器学习应用的流程 k近邻算法 k近邻算法整体是这样的一个算法&#xff0c;我们已经知道的这些数据点其实是…...

ChatGPT:理解HTTP请求数据格式:JSON、x-www-form-urlencoded和form-data

ChatGPT&#xff1a;理解HTTP请求数据格式&#xff1a;JSON、x-www-form-urlencoded和form-data 使用postman发送一个post请求&#xff0c;在body里面加上了form-data数据&#xff0c;namexxx&#xff0c;age23&#xff0c;为什么输出request.body()得到的是这样的结果 -------…...

字符集、IO流(一)

字符集、IO流(一) 各位同学,前面我们已经学习了File类,通过File类的对象可以对文件进行操作,但是不能操作文件中的内容。要想操作文件中的内容,我们还得学习IO流。但是在正式学习IO流之前,我们还需要学习一个前置知识叫做字符集,只有我们把字符集搞明白了,再学习IO流…...

相乘(蓝桥杯)

相乘 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小蓝发现&#xff0c;他将 1 至 1000000007 之间的不同的数与 2021 相乘后再求除以 1000000007 的余数&#xff0c;会得到不同的数。 小蓝想知道&#xff0c;能不能在 1 …...

[AFCTF 2018]你能看出这是什么加密么

最开始是我对rsa的小小的理解 rsa也就是非对称加密算法&#xff0c;拥有公开的加密密钥和解密密钥&#xff0c;这也是我们写脚本的基础 选取素数p和q&#xff0c;计算乘积npq&#xff0c;以及(n)(p-1)(q-1)。&#xff08;欧拉函数&#xff09; 选择一个e值作为密钥…...

基于springboot+vue的重庆旅游网(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...