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

深入剖析链表反转:多语言实现与高级语法特性20240924

深入剖析链表反转:多语言实现与高级语法特性

引言

在数据结构与算法的学习中,链表是基础结构之一,尤其在动态内存分配和操作中体现了它的重要性。今天,我们将通过反转单链表这一经典算法题,从不同编程语言的角度进行实现,通过分析各自的实现细节和高级语法特性,加深对不同语言的理解。


问题描述

实现一个函数,用于反转单链表,具体任务包括:

  1. 定义链表节点的结构。
  2. 编写反转链表的函数。
  3. 提供创建和打印链表的辅助函数。
  4. 执行测试用例并展示结果。

链表反转的基本操作

可以总结为以下步骤:
1. 前驱节点:初始为 nullptr(或 None)。
2. 当前节点:初始为链表头 head。
3. 循环:持续到当前节点为 nullptr或 None。
• 保存下一节点:保存当前节点的下一节点以防止断链。
• 反转指针:将当前节点的 next 指向前驱节点。
• 前驱节点前移:将前驱节点移至当前节点。
• 当前节点前移:将当前节点移至下一节点,继续下一次循环。


Python 实现:简洁与动态类型的结合

Python 代码实现

from typing import Optional, List# 定义链表节点的结构
class ListNode:def __init__(self, val: int = 0, next: Optional['ListNode'] = None):self.val = valself.next = next# 反转链表函数
class Solution:def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:prev = Nonecurrent = headwhile current:next_node = current.nextcurrent.next = prevprev = currentcurrent = next_nodereturn prev# 辅助函数:创建链表
def create_linked_list(values: List[int]) -> Optional[ListNode]:if not values:return Nonehead = ListNode(values[0])current = headfor val in values[1:]:current.next = ListNode(val)current = current.nextreturn head# 辅助函数:打印链表
def print_list(head: Optional[ListNode]) -> None:current = headwhile current:print(current.val, end=' -> ' if current.next else '\n')current = current.next# 测试代码
if __name__ == "__main__":test_cases = [[1, 2, 3, 4, 5],       # 测试用例 1[1, 2],                # 测试用例 2[],                    # 测试用例 3:空列表[42],                  # 测试用例 4:只有一个节点]solution = Solution()for idx, values in enumerate(test_cases, start=1):print(f"测试用例 {idx} - 原始链表:")head = create_linked_list(values)print_list(head)reversed_head = solution.reverseList(head)print(f"测试用例 {idx} - 反转后的链表:")print_list(reversed_head)print('-' * 40)

重点语法与用法解析

1. 变量类型注解:
变量类型注解是 Python 3.6 引入的特性,允许在变量声明时指定类型。例如,Optional[ListNode] 表示该变量可以是 ListNode 类型,也可以是 None。这种类型注解的标准语法为 变量名: 类型 = 值。使用类型注解提高了代码的可读性和可维护性,同时也方便静态类型检查工具(如 mypy)对代码进行检查。
2. Optional 类型:
在链表的实现中,Python 的 Optional 类型允许链表的头节点为空。这对于处理空链表和递归操作非常重要。
3. 动态内存管理:
Python 内置了垃圾回收机制,因此开发者不需要像 C/C++ 那样手动释放内存。这极大地简化了链表的实现过程。

运行结果

测试用例 1 - 原始链表:
1 -> 2 -> 3 -> 4 -> 5
测试用例 1 - 反转后的链表:
5 -> 4 -> 3 -> 2 -> 1
----------------------------------------
测试用例 2 - 原始链表:
1 -> 2
测试用例 2 - 反转后的链表:
2 -> 1
----------------------------------------
测试用例 3 - 原始链表:
测试用例 3 - 反转后的链表:
----------------------------------------
测试用例 4 - 原始链表:
42
测试用例 4 - 反转后的链表:
42
----------------------------------------

Python 实现解析

Python 中,通过类型提示和简洁的 while 循环,我们可以轻松实现链表反转。创建和打印链表的辅助函数使得我们能够方便地处理和展示链表内容。Python 不需要显式的内存管理,这使得编写链表操作变得简便,适合用于算法学习和快速原型开发。


Go 实现:静态类型与简洁并发

Go 代码实现

package mainimport ("fmt"
)// 定义链表节点结构
type ListNode struct {Val  intNext *ListNode
}// 反转链表函数
func reverseList(head *ListNode) *ListNode {var prev *ListNodecurrent := headfor current != nil {nextNode := current.Nextcurrent.Next = prevprev = currentcurrent = nextNode}return prev
}// 辅助函数:创建链表
func createLinkedList(values []int) *ListNode {if len(values) == 0 {return nil}head := &ListNode{Val: values[0]}current := headfor _, val := range values[1:] {current.Next = &ListNode{Val: val}current = current.Next}return head
}// 辅助函数:打印链表
func printList(head *ListNode) {current := headfor current != nil {if current.Next != nil {fmt.Printf("%d -> ", current.Val)} else {fmt.Printf("%d\n", current.Val)}current = current.Next}
}// 主函数:测试代码
func main() {testCases := [][]int{{1, 2, 3, 4, 5},    // 测试用例 1{1, 2},             // 测试用例 2{},                 // 测试用例 3:空列表{42},               // 测试用例 4:只有一个节点}for idx, values := range testCases {fmt.Printf("测试用例 %d - 原始链表:\n", idx+1)head := createLinkedList(values)printList(head)reversedHead := reverseList(head)fmt.Printf("测试用例 %d - 反转后的链表:\n", idx+1)printList(reversedHead)fmt.Println("----------------------------")}
}

运行结果

测试用例 1 - 原始链表:
1 -> 2 -> 3 -> 4 -> 5
测试用例 1 - 反转后的链表:
5 -> 4 -> 3 -> 2 -> 1
----------------------------
测试用例 2 - 原始链表:
1 -> 2
测试用例 2 - 反转后的链表:
2 -> 1
----------------------------
测试用例 3 - 原始链表:
测试用例 3 - 反转后的链表:
----------------------------
测试用例 4 - 原始链表:
42
测试用例 4 - 反转后的链表:
42
----------------------------

Go 实现解析

Go 的静态类型系统确保了代码在编译时检测到潜在的错误,避免了运行时的一些常见问题。通过 for 循环与指针操作实现链表反转,Go 代码结构简洁明了,易于理解。此外,Go 的自动内存管理机制使得链表操作更加安全。Go 语言适合用于需要高性能和高并发的场景。


C 语言实现:指针与手动内存管理

C 代码实现

#include <stdio.h>
#include <stdlib.h>// 定义链表节点结构
typedef struct ListNode {int val;struct ListNode* next;
} ListNode;// 反转链表函数
ListNode* reverseList(ListNode* head) {ListNode* prev = NULL;ListNode* current = head;while (current != NULL) {ListNode* nextNode = current->next;current->next = prev;prev = current;current = nextNode;}return prev;
}// 辅助函数:创建链表
ListNode* createLinkedList(int* values, int size) {if (size == 0) return NULL;ListNode* head = (ListNode*)malloc(sizeof(ListNode));head->val = values[0];head->next = NULL;ListNode* current = head;for (int i = 1; i < size; i++) {current->next = (ListNode*)malloc(sizeof(ListNode));current = current->next;current->val = values[i];current->next = NULL;}return head;
}// 辅助函数:打印链表
void printList(ListNode* head) {while (head != NULL) {printf("%d", head->val);if (head->next != NULL) {printf(" -> ");}head = head->next;}printf("\n");
}// 辅助函数:释放链表内存
void freeList(ListNode* head) {ListNode* tmp;while (head != NULL) {tmp = head;head = head->next;free(tmp);}
}// 主函数:测试代码
int main() {int test1[] = {1, 2, 3, 4, 5};int test2[] = {1, 2};int test3[] = {};int test4[] = {42};ListNode* testCases[] = {createLinkedList(test1, 5),createLinkedList(test2, 2),createLinkedList(test3, 0),createLinkedList(test4, 1)};for (int i = 0; i < 4; i++) {printf("测试用例 %d - 原始链表:\n", i + 1);printList(testCases[i]);ListNode* reversedHead = reverseList(testCases[i]);printf("测试用例 %d - 反转后的链表:\n", i + 1);printList(reversedHead);printf("----------------------------\n");freeList(reversedHead);}return 0;
}

运行结果

测试用例 1 - 原始链表:
1 -> 2 -> 3 -> 4 -> 5
测试用例 1 - 反转后的链表:
5 -> 4 -> 3 -> 2 -> 1
----------------------------
测试用例 2 - 原始链表:
1 -> 2
测试用例 2 - 反转后的链表:
2 -> 1
----------------------------
测试用例 3 - 原始链表:
测试用例 3 - 反转后的链表:
----------------------------
测试用例 4 - 原始链表:
42
测试用例 4 - 反转后的链表:
42
----------------------------

C 实现解析

在 C 中,链表反转的实现需要精细的指针操作,同时,手动管理内存的分配和释放是必须的。通过 malloc 分配内存并通过 free 释放内存,避免内存泄漏。在嵌入式和系统编程中,C 语言的这种手动控制对于精细化优化至关重要。


C++ 实现:面向对象与智能指针

C++ 代码实现

#include <iostream>
#include <vector>// 定义链表节点结构
struct ListNode {int val;ListNode* next;ListNode(int x) : val(x), next(nullptr) {}
};// 反转链表函数
ListNode* reverseList(ListNode* head) {ListNode* prev = nullptr;ListNode* current = head;while (current != nullptr) {ListNode* nextNode = current->next;current->next = prev;prev = current;current = nextNode;}return prev;
}// 辅助函数:创建链表
ListNode* createLinkedList(const std::vector<int>& values) {if (values.empty()) return nullptr;ListNode* head = new ListNode(values[0]);ListNode* current = head;for (size_t i = 1; i < values.size(); i++) {current->next = new ListNode(values[i]);current = current->next;}return head;
}// 辅助函数:打印链表
void printList(ListNode* head) {while (head != nullptr) {std::cout << head->val;if (head->next != nullptr) {std::cout << " -> ";}head = head->next;}std::cout << std::endl;
}// 辅助函数:释放链表内存
void freeList(ListNode* head) {while (head != nullptr) {ListNode* nextNode = head->next;delete head;head = nextNode;}
}// 主函数:测试代码
int main() {std::vector<std::vector<int>> testCases = {{1, 2, 3, 4, 5},{1, 2},{},{42}};for (size_t i = 0; i < testCases.size(); ++i) {std::cout << "测试用例 " << i + 1 << " - 原始链表:" << std::endl;ListNode* head = createLinkedList(testCases[i]);printList(head);ListNode* reversedHead = reverseList(head);std::cout << "测试用例 " << i + 1 << " - 反转后的链表:" << std::endl;printList(reversedHead);std::cout << "----------------------------" << std::endl;freeList(reversedHead);}return 0;
}

重点语法与用法解析

1. 构造函数的使用:
ListNode(int x) : val(x), next(nullptr) {}

这是 ListNode 类的构造函数,使用了 成员初始化列表 直接初始化成员变量。成员初始化列表的优势在于避免了先调用默认构造函数再赋值的额外步骤,确保成员变量在对象创建时被正确、高效地初始化,从而提高程序的性能并避免未定义行为。构造函数不仅是 C++ 面向对象编程的核心部分,也是现代 C++ 编程的最佳实践。

2. std::vector 的使用:

在 C++ 中,std::vector 是一个动态数组,它提供了灵活且安全的内存管理,相比 C 的数组,它自动调整大小并且自动管理内存。我们可以通过 push_back 向 vector 中添加元素,无需担心内存分配和管理问题。
• 动态大小调整:相比 C 语言中的数组大小固定,std::vector 可以根据需要自动调整大小,避免手动使用 malloc 和 realloc 来管理内存。
• 内存管理:std::vector 的内存由其自动管理,当 vector 超出作用域时,会自动释放内存,减少了内存泄漏的风险。

3. 资源安全性:

std::vector 和现代 C++ 的内存管理机制使得程序更加健壮且易于维护。通过 delete 手动释放内存确保了内存的高效管理,防止内存泄漏。

运行结果

测试用例 1 - 原始链表:
1 -> 2 -> 3 -> 4 -> 5
测试用例 1 - 反转后的链表:
5 -> 4 -> 3 -> 2 -> 1
----------------------------
测试用例 2 - 原始链表:
1 -> 2
测试用例 2 - 反转后的链表:
2 -> 1
----------------------------
测试用例 3 - 原始链表:
测试用例 3 - 反转后的链表:
----------------------------
测试用例 4 - 原始链表:
42
测试用例 4 - 反转后的链表:
42
----------------------------

C++ 实现解析

C++ 使用构造函数来简化链表节点的初始化,通过 newdelete 管理内存。在现代 C++ 中,使用智能指针如 std::shared_ptr 可以进一步简化内存管理。C++ 结合了面向对象和底层指针操作的优点,既保留了性能,又提升了代码的可维护性。


总结

在本文中,我们通过反转链表这一经典算法题,分别使用了 Python、Go、C 和 C++ 四种语言实现。通过这种多语言的实现对比,读者不仅可以加深对链表反转算法的理解,也能更深入地掌握各语言的特点和高级语法特性。还着重分析了每个语言中一些关键的高级语法特性:

•	Python 中的 类型注解 和 Optional 类型 帮助提高代码的可读性,并支持静态类型检查工具的使用。
•	C++ 中的 构造函数 和 成员初始化列表 确保了数据在对象创建时得到正确的初始化,而 std::vector 则提供了高效、安全的动态内存管理。

通过这些对比,读者不仅能够理解链表反转的算法实现,还能够更深入地掌握不同语言的独特特性和最佳实践。在实际开发中,这种对比和分析能够帮助开发者做出更好的技术选型。

相关文章:

深入剖析链表反转:多语言实现与高级语法特性20240924

深入剖析链表反转&#xff1a;多语言实现与高级语法特性 引言 在数据结构与算法的学习中&#xff0c;链表是基础结构之一&#xff0c;尤其在动态内存分配和操作中体现了它的重要性。今天&#xff0c;我们将通过反转单链表这一经典算法题&#xff0c;从不同编程语言的角度进行…...

【数据结构初阶】链式二叉树接口实现超详解

文章目录 1. 节点定义2. 前中后序遍历2. 1 遍历规则2. 2 遍历实现2. 3 结点个数2. 3. 1 二叉树节点个数2. 3. 2 二叉树叶子节点个数2. 3. 3 二叉树第k层节点个数 2. 4 二叉树查找值为x的节点2. 5 二叉树层序遍历2. 6 判断二叉树是否是完全二叉树 3. 二叉树性质 1. 节点定义 用…...

力扣189 轮转数组 Java版本

文章目录 题目描述代码 题目描述 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4…...

RMAN异机恢复数据库记录

场景&#xff1a;数据库服务器宕机&#xff0c;无法恢复 处理&#xff1a;使用备份资料进行异地恢复 1.此处环境为同平台、同版本&#xff08;操作系统版本可以不同&#xff0c;但数据库版本需相同&#xff09;&#xff0c;源机器和目标机器具有相同的目录结构。 2.目标机器只…...

JVM 调优篇7 调优案例4- 线程溢出

一 线程溢出 1.1 报错信息 每个 Java 线程都需要占用一定的内存空间&#xff0c;当 JVM 向底层操作系统请求创建一个新的 native 线程时&#xff0c;如果没有足够的资源分配就会报此类错误。报错信息&#xff1a;java.lang.outofmemoryError:unable to create new Native Thr…...

C++类与对象(三)

目录 1.再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit关键字 2.STATIC成员 2.1 概念 2.2 特性 3.C中成员初始化的新玩法 4.友元 4.1 友元函数 4.2 友元类 5.内部类 6.再次理解封装 7.再次理解面向对象 本次内容大纲&#xff1a; 1.再谈构造函数 …...

云栖实录 | 阿里云 OpenLake 解决方案重磅发布:多模态数据统一纳管、引擎平权联合计算、数据共享统一读写

新一轮人工智能浪潮正在重塑世界&#xff0c;以生成式 AI 为代表的技术快速应用&#xff0c;推动了数据与智能的深化融合&#xff0c;同时也给数据基础设施带来了全新的变革与挑战。面向 AI 时代的数据基础设施如何构建&#xff1f;底层数据平台架构在 AI 时代如何演进&#xf…...

《线性代数》学渣笔记

文章目录 1 行列式1.1 克拉默法则1.2 基本性质1.3 余子式 M i j M_{ij} Mij​1.4 代数余子式 A i j ( − 1 ) i j ⋅ M i j A_{ij} (-1)^{ij} \cdot M_{ij} Aij​(−1)ij⋅Mij​1.5 具体型行列式计算&#xff08;化为基本型&#xff09;1.5.1 主对角线行列式&#xff1a;主…...

对网页聊天项目进行性能测试, 使用JMeter对于基于WebSocket开发的webChat项目的聊天功能进行测试

登录功能 包括接口的设置和csv文件配置 ​​​​​​ 这里csv文件就是使用xlsx保存数据, 然后在浏览器找个网址转成csv文件 注册功能 这里因为需要每次注册的账号不能相同, 所以用了时间函数来当用户名, 保证尽可能的给正确的注册数据, 时间函数使用方法如下 这里输入分钟, 秒…...

《程序猿之设计模式实战 · 适配器模式》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…...

Elasticsearch案例

目录 一、创建索引 二、准备数据 三、环境搭建 &#xff08;1&#xff09;环境搭建 &#xff08;2&#xff09;创建实体类 &#xff08;3&#xff09;实现Repository接口 四、实现自动补全功能 五、实现高亮搜索关键字功能 &#xff08;1&#xff09;在repository接口中…...

SpringBoot 项目如何使用 pageHelper 做分页处理 (含两种依赖方式)

分页是常见大型项目都需要的一个功能&#xff0c;PageHelper是一个非常流行的MyBatis分页插件&#xff0c;它支持多数据库分页&#xff0c;无需修改SQL语句即可实现分页功能。 本文在最后展示了两种依赖验证的结果。 文章目录 一、第一种依赖方式二、第二种依赖方式三、创建数…...

GSR关键词排名系统是针对谷歌seo的吗?

是的&#xff0c;GSR关键词排名系统专门针对谷歌SEO&#xff0c;具体通过外部优化手段快速提升关键词排名。不同于传统的SEO策略&#xff0c;GSR系统并不依赖于对网站内容的调整或内部优化&#xff0c;完全通过站外操作实现效果。这意味着&#xff0c;用户不需要花费精力在网站…...

HarmonyOS Next开发----使用XComponent自定义绘制

XComponent组件作为一种绘制组件&#xff0c;通常用于满足用户复杂的自定义绘制需求&#xff0c;其主要有两种类型"surface和component。对于surface类型可以将相关数据传入XComponent单独拥有的NativeWindow来渲染画面。 由于上层UI是采用arkTS开发&#xff0c;那么想要…...

什么是电商云手机?可以用来干什么?

随着电商行业的迅速发展&#xff0c;云手机作为一种创新工具正逐渐进入出海电商领域。专为外贸市场量身定制的出海电商云手机&#xff0c;已经成为许多外贸企业和出海电商卖家的必备。本文将详细介绍电商云手机是什么以及可以用来做什么。 与国内云手机偏向于游戏场景不同&…...

Python 2 和 Python 3的差异

Python 2 和 Python 3 之间有许多差异&#xff0c;Python 3 是 Python 语言的更新版本&#xff0c;目的是解决 Python 2 中的一些设计缺陷&#xff0c;并引入更现代的编程方式。以下是 Python 2 和 Python 3 之间的一些主要区别&#xff1a; 文章目录 1. print 语句2. 整除行为…...

Leetcode 第 139 场双周赛题解

Leetcode 第 139 场双周赛题解 Leetcode 第 139 场双周赛题解题目1&#xff1a;3285. 找到稳定山的下标思路代码复杂度分析 题目2&#xff1a;3286. 穿越网格图的安全路径思路代码复杂度分析 题目3&#xff1a;3287. 求出数组中最大序列值思路代码复杂度分析 题目4&#xff1a;…...

spring 注解 - @NotEmpty - 确保被注解的字段不为空,而且也不是空白(即不是空字符串、不是只包含空格的字符串)

NotEmpty 是 Bean Validation API 提供的注解之一&#xff0c;用于确保被注解的字段不为空。它检查字符串不仅不是 null&#xff0c;而且也不是空白&#xff08;即不是空字符串、不是只包含空格的字符串&#xff09;。 这个注解通常用在 Java 应用程序中&#xff0c;特别是在处…...

深入理解华为仓颉语言的数值类型

解锁Python编程的无限可能&#xff1a;《奇妙的Python》带你漫游代码世界 在编程过程中&#xff0c;数据处理是开发者必须掌握的基本技能之一。无论是开发应用程序还是进行算法设计&#xff0c;了解不同数据类型的特性和用途都至关重要。本文将深入探讨华为仓颉语言中的基本数…...

WPF 的TreeView的TreeViewItem下动态生成TreeViewItem

树形结构仅部分需要动态生成TreeViewItem的可以参考本文。 xaml页面 <TreeView MinWidth"220" ><TreeViewItem Header"功能列表" ItemsSource"{Binding Functions}"><TreeViewItem.ItemTemplate><HierarchicalDataTempla…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上

一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema&#xff0c;不需要复杂的查询&#xff0c;只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 &#xff1a;在几秒钟…...

Easy Excel

Easy Excel 一、依赖引入二、基本使用1. 定义实体类&#xff08;导入/导出共用&#xff09;2. 写 Excel3. 读 Excel 三、常用注解说明&#xff08;完整列表&#xff09;四、进阶&#xff1a;自定义转换器&#xff08;Converter&#xff09; 其它自定义转换器没生效 Easy Excel在…...

Excel 怎么让透视表以正常Excel表格形式显示

目录 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总...

AI书签管理工具开发全记录(十八):书签导入导出

文章目录 AI书签管理工具开发全记录&#xff08;十八&#xff09;&#xff1a;书签导入导出1.前言 &#x1f4dd;2.书签结构分析 &#x1f4d6;3.书签示例 &#x1f4d1;4.书签文件结构定义描述 &#x1f523;4.1. ​整体文档结构​​4.2. ​核心元素类型​​4.3. ​层级关系4.…...

React与原生事件:核心差异与性能对比解析

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