当前位置: 首页 > 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…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

Linux基础开发工具——vim工具

文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...

python打卡第47天

昨天代码中注意力热图的部分顺移至今天 知识点回顾&#xff1a; 热力图 作业&#xff1a;对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图&#xff0c;展示模…...

2025 后端自学UNIAPP【项目实战:旅游项目】7、景点详情页面【完结】

1、获取景点详情的请求【my_api.js】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http(/login/getWXSessionKey, {code,avatar}); };//…...

MCP和Function Calling

MCP MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09; &#xff0c;2024年11月底&#xff0c;由 Anthropic 推出的一种开放标准&#xff0c;旨在统一大模型与外部数据源和工具之间的通信协议。MCP 的主要目的在于解决当前 AI 模型因数据孤岛限制而…...