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

Java 数据结构篇-实现双链表的核心API

🔥博客主页: 小扳_-CSDN博客
❤感谢大家点赞👍收藏⭐评论✍
 

 

 

文章目录

        1.0 双链表的说明

        1.1 双链表 - 创建

        1.2 双链表 - 根据索引查找节点

        1.3 双链表 - 根据索引插入节点

        1.4 双链表 - 头插节点

        1.5 双链表 - 尾插

        1.6 双链表 - 根据索引来删除节点

        1.7 头删节点

        1.8 尾删节点

        1.9 实现迭代器循环

        2.0 双链表完整的实现代码

        3.0 环形双链表的说明

        3.1 环形双链表 - 创建

        3.2 环形双链表 - 头插节点

        3.3 环形双链表 - 尾插节点

        3.4 环形双链表 - 头删节点

        3.5 环形双链表 - 尾删节点

        3.6 环形链表 - 根据值来删除节点

        4.0 环形双链表完整的实现代码


        1.0 双链表的说明

        双链表是一种数据结构,其中每个节点包含两个指针一个指向前一个节点一个指向后一个节点。双链表可以在任意位置插入或删除节点,而不需要像单链表那样遍历整个链表来找到需要操作的位置。双链表可以用于实现栈、队列、以及其他需要快速插入和删除操作的数据结构。由于每个节点包含两个指针,双链表的内存占用量通常比单链表更大

        1.1 双链表 - 创建

        把双链表封装成一个类,类中还需要封装一个节点类 Node,该节点类的成员有指向前一个节点的变量 Node prev,值 value ,指向后一个节点的变量 Node next

代码如下:

public class MyDoubleLists{private final Node hand;private final Node tail;private static class Node {public Node prev;public Node next;public int value;public Node(Node prev, int value, Node next) {this.prev = prev;this.next = next;this.value = value;}}public MyDoubleLists() {hand = new Node(null,0,null);tail = new Node(hand,-1,null);hand.next = tail;tail.prev = hand;}}

         注意外部类中,还需要定义头节点,尾节点,再利用外部类的构造器中就可以完成对头尾节点的初始化了。内部类中的节点类建议用静态来修饰。

        1.2 双链表 - 根据索引查找节点

        由于这个方法可以为其他几个方法提供服务,因此,把这个方法独立出来。实现思路为:开始的节点应为 hand,循环终止条件为:p == tail 当指向尾节点的那一刻就该结束循环了。还要加一个变量 i = -1 ,每一次循环结束要进行 i++ ,当 i == index 时,找到了该索引的节点,返回该节点即可,若循环结束还是没找到,就得返回 null

代码如下:

    //根据索引查找节点private Node findNode(int index) {int i = -1;for (Node p = hand; p !=tail ; p = p.next,i++){if (i == index) {return p;}}return null;}

        这个方法一般不会对外开发,因此,加上 private 来修饰,当 i == -1 时,返回的时头节点,所以一开始的节点为 hand 。对外是索引从 0 开始才会存储值的,对于头节点存储什么值是不关心的。

        1.3 双链表 - 根据索引插入节点

         根据索引插入节点,提前需要准备好该节点的前一个节点 prev、该节点的后一个节点 next 。通过以上已经实现的方法来找到插入位置的前一个结点,prev = findNode(index - 1),后一个节点也就可以找到了,next = prev.next

代码如下:

    //根据索引插入节点public void insert(int index, int value) {Node p = findNode(index - 1);if (p == null){throw new RuntimeException("用索引访问失败");}Node prev = p;Node next = prev.next;Node insertNode = new Node(prev, value,next);prev.next = insertNode;next.prev = insertNode;}

        prev.next 指向新的节点next.prev 指向上一个节点。新的节点的头节点的引用为 prev,尾节点为 next 。 

         1.4 双链表 - 头插节点

        其实这个方法就比较简单了,这个就是根据索引 0 来插入节点的,就是一个索引等于0的特例,所以可以直接调用已经实现的 insert(0,int value) 方法。

代码如下:

    //头插节点public void addFirst(int value) {insert(0,value);}

         1.5 双链表 - 尾插

        对尾部的操作是双链表的一个很大的优势,对尾部的查询、增加节点、删除节点效率都很快,因为对尾节点是有记录的,就不用从头开始来查找尾部节点了,直接可以得到。

        实现方法的思路为:需要找到插入的前一个节点插入的后一个节点肯定是尾节点,所以,可以通过   prev =  tail.prev,来找到插入的前一个节点。

代码如下:

    //尾插节点public void addLast(int value) {Node lats = tail;Node prev = lats.prev;Node addNode = new Node(prev,value,lats);prev.next = addNode;lats.prev = addNode;}

        新的节点的前一个节点为 prev ,后节点为 tail,prev.next 与 tail.prev 就要更改为指向新的节点了。

        1.6 双链表 - 根据索引来删除节点

        先通过已经实现的 findNode() 方法来找到该索引的节点,还有找到删除该节点的前一个节点与后一个节点。

代码如下:

    //根据索引来删除节点public void remove(int index) {Node prev = findNode(index - 1);if (prev == null) {throw new RuntimeException("用索引来删除数据失败!");}Node remove = prev.next;if (remove == tail) {throw new RuntimeException("用索引来删除数据失败!");}Node next = remove.next;prev.next = next;next.prev = next;}

         接着就可以将要删除的前一个节点指向要删除的节点后一个节点,但是考虑两种情况,第一种,当要删除的节点没找到,就要抛出异常了。第二种,当发现要删除的节点为 tail 时需要抛出异常,总不能自己把自己的尾巴 "切了吧" 然而不用考虑是否把头节点删除,因为要删除的节点总是拿不到头节点。

         1.7 头删节点

        当索引为0时,就是头删,是 remove(0) 方法的一个特例。可以直接来调用根据索引来删除节点的方法。

代码如下:

    //头删节点public void removeFirst() {remove(0);}

         1.8 尾删节点

        双链表尾删的效率是很高的,因为对尾节点是有记录的。

代码如下:

    //尾删节点public void removeLast() {Node remove = tail.prev;if (remove == hand){throw new RuntimeException();}Node prev = remove.prev;prev.next = tail;tail.prev = prev;}

        需要找到三个节点,要删除的节点、删除节点的前一个节点、还有尾节点。需要注意的是,判断要删除的节点为头节点,需要抛出异常,总不能自己把自己的 " 头部 " 给切了吧。

         1.9 实现迭代器循环

        这个完成 Iterable 接口,创建新的该接口子类对象,重写两个方法即可。

代码如下:

    //实现迭代器循环@Overridepublic Iterator<Integer> iterator() {return new Iterator<Integer>() {Node p = hand.next;@Overridepublic boolean hasNext() {return p != tail;}@Overridepublic Integer next() {int value = p.value;p = p.next;return value;}};}

        需要注意的是,头节点的值是不用在乎的,所以遍历开始为 hand.next ,循环结束条件为,p == tail,遍历到尾节点就要终止了。

        2.0 双链表完整的实现代码

 

import java.util.Iterator;public class MyDoubleLists implements Iterable<Integer>{private final Node hand;private final Node tail;private static class Node {public Node prev;public Node next;public int value;public Node(Node prev, int value, Node next) {this.prev = prev;this.next = next;this.value = value;}}public MyDoubleLists() {hand = new Node(null,0,null);tail = new Node(hand,-1,null);hand.next = tail;tail.prev = hand;}//根据索引查找节点private Node findNode(int index) {int i = -1;for (Node p = hand; p !=tail ; p = p.next,i++){if (i == index) {return p;}}return null;}//根据索引插入节点public void insert(int index, int value) {Node p = findNode(index - 1);if (p == null){throw new RuntimeException("用索引访问失败");}Node prev = p;Node next = prev.next;Node insertNode = new Node(prev, value,next);prev.next = insertNode;next.prev = insertNode;}//头插节点public void addFirst(int value) {insert(0,value);}//尾插节点public void addLast(int value) {Node lats = tail;Node prev = lats.prev;Node addNode = new Node(prev,value,lats);prev.next = addNode;lats.prev = addNode;}//根据索引来删除节点public void remove(int index) {Node prev = findNode(index - 1);if (prev == null) {throw new RuntimeException("用索引来删除数据失败!");}Node remove = prev.next;if (remove == tail) {throw new RuntimeException("用索引来删除数据失败!");}Node next = remove.next;prev.next = next;next.prev = next;}//头删节点public void removeFirst() {remove(0);}//尾删节点public void removeLast() {Node remove = tail.prev;if (remove == hand){throw new RuntimeException();}Node prev = remove.prev;prev.next = tail;tail.prev = prev;}//根据索引来查询数据public int get(int index) {Node find = findNode(index);if (find == null){throw new RuntimeException("根据该索引找不到数据");}return find.value;}//实现迭代器循环@Overridepublic Iterator<Integer> iterator() {return new Iterator<Integer>() {Node p = hand.next;@Overridepublic boolean hasNext() {return p != tail;}@Overridepublic Integer next() {int value = p.value;p = p.next;return value;}};}}

        3.0 环形双链表的说明

        环形双链表是一种数据结构,它类似于双向链表,但是链表的最后一个节点指向第一个节点,形成一个环形结构。简单来说,先对比与一般的双链表,环形双链表就是头尾节点都是同一个节点

        3.1 环形双链表 - 创建

        把环形双链表看成一个对象,该类中需要封装一个节点的内部类,对外不开放的,需要用限制修饰符来修饰。外部类中的成员变为 sentinel ,即作为头节点,也作为尾节点

代码如下:

public class MyAnnularDoubleList{private final Node sentinel;private static class Node {public Node prev;public int value;public Node next;public Node(Node prev, int value, Node next) {this.prev = prev;this.value = value;this.next = next;}}public MyAnnularDoubleList() {sentinel = new Node(null,0,null);sentinel.prev = sentinel;sentinel.next = sentinel;}}

        在创建环形双链表时,在用无参构造器就可以先把 sentinel 初始化了。

        3.2 环形双链表 - 头插节点

        根据 next =  sentinel.next 就可以得到插入点的下一个节点,就可以把新节点的指向的前一个节点来指向 sntinel,新节点的指向后一个节点来指向 next

        这里需要考虑一种情况,假设,该环形双链表中就只有一个 sentinel 节点,以上阐述的思路还能不能用呢?答案时可以的,如果实在理解不了的话,可以把一个 sentinel 节点,想象成两个 sentinel 节点,效果都是一样的,都是指向自己嘛。

代码如下:

    //头插节点public void addFirst(int value) {Node hand = sentinel;Node tail = sentinel.next;Node addNode = new Node(hand,value,tail);hand.next = addNode;tail.prev = addNode;}

        3.3 环形双链表 - 尾插节点

        根据 prev = sentinel.prev 来找到插入节点的前一个的节点,插入节点的后一个节点就是 sentinel ,新节点的指向前的节点为 prev,新节点的指向后的节点为 sentinel ,接着 prev.next 指向新节点,sentinel.prev 指向新节点。

代码如下:

    //尾插节点public void addLast(int value) {Node prev = sentinel.prev;Node next = sentinel;Node addNode = new Node(prev,value,next);prev.next = addNode;next.prev = addNode;}

        同理,不需要额外考虑当节点只有一个时,以上代码依旧可以实现尾插节点。

        3.4 环形双链表 - 头删节点

        根据 remove = sentinel.next ,可以得到需要删除的节点,再由 next = remove.next,得到删除节点的后一个节点,这样三个节点后已知了,santinel.next 指向 next ,next.prev 指向sentinel ,剩下的没有被引用的节点(对象),会被 JVM 自动回收

代码如下:

    //头删节点public void removeFirst() {Node remove = sentinel.next;if (remove == sentinel) {throw new RuntimeException("删除失败!");}Node next = remove.next;sentinel.next = next;next.prev = sentinel;}

        需要注意的是,当删除的节点为 sentinel 需要抛出异常,但是个人感觉不加判断也可以,sentinel 根本不会被删除,即使只有 sentinel 一直被删除。

        3.5 环形双链表 - 尾删节点

        根据 remove = sentinel.prev 得到需要删除的节点,通过 prev = remove.prev 得到需要删除的前一个节点,prev.next 指向 sentinelsentinel.prev 指向 prev 即可。

代码如下:

    //尾删节点public void removeLast() {Node remove = sentinel.prev;Node prev = remove.prev;prev.next = sentinel;sentinel.prev = prev;}

        同样的,当删除的节点为 sentinel 需要抛出异常,但是个人感觉不加判断也可以,sentinel 根本不会被删除,即使只有 sentinel 一直被删除。

         3.6 环形链表 - 根据值来删除节点

        先独立一个方法,根据值来查询节点,一开始的循环节点为 sentinel.next ,对于 sentinel 里面的值是什么根本不在乎的。循环终止条件为:p == sentinel 已经转完一圈了。找到就返回该节点,找不到就返回 null 。删除的原理是一样的,得先找到三个节点,然后把前后节点直接关联起来。

代码如下:

    //根据值来删除节点private Node findValue (int value) {for (Node p = sentinel.next; p != sentinel; p = p.next) {if (p.value == value) {return p;}}return null;}public void removeValue (int value) {Node remove = findValue(value);if (remove == null) {throw new RuntimeException("找不到该数据来删除相对应的节点");}Node prev = remove.prev;Node next = remove.next;prev.next = next;next.prev = prev;}

        需要注意的是,当接收到的节点为 null 时,需要抛出异常,找不到对应该值的节点。

        4.0 环形双链表完整的实现代码

import java.util.Iterator;public class MyAnnularDoubleList implements Iterable<Integer>{private final Node sentinel;private static class Node {public Node prev;public int value;public Node next;public Node(Node prev, int value, Node next) {this.prev = prev;this.value = value;this.next = next;}}public MyAnnularDoubleList() {sentinel = new Node(null,0,null);sentinel.prev = sentinel;sentinel.next = sentinel;}//头插节点public void addFirst(int value) {Node hand = sentinel;Node tail = sentinel.next;Node addNode = new Node(hand,value,tail);hand.next = addNode;tail.prev = addNode;}//尾插节点public void addLast(int value) {Node prev = sentinel.prev;Node next = sentinel;Node addNode = new Node(prev,value,next);prev.next = addNode;next.prev = addNode;}//头删节点public void removeFirst() {Node remove = sentinel.next;if (remove == sentinel) {throw new RuntimeException("删除失败!");}Node next = remove.next;sentinel.next = next;next.prev = sentinel;}//尾删节点public void removeLast() {Node remove = sentinel.prev;Node prev = remove.prev;prev.next = sentinel;sentinel.prev = prev;}//根据值来删除节点private Node findValue (int value) {for (Node p = sentinel.next; p != sentinel; p = p.next) {if (p.value == value) {return p;}}return null;}public void removeValue (int value) {Node remove = findValue(value);if (remove == null) {throw new RuntimeException("找不到该数据来删除相对应的节点");}Node prev = remove.prev;Node next = remove.next;prev.next = next;next.prev = prev;}//实现迭代器@Overridepublic Iterator<Integer> iterator() {return new Iterator<Integer>() {Node p = sentinel.next;@Overridepublic boolean hasNext() {return p != sentinel;}@Overridepublic Integer next() {int value = p.value;p = p.next;return value;}};}
}

相关文章:

Java 数据结构篇-实现双链表的核心API

&#x1f525;博客主页&#xff1a; 小扳_-CSDN博客 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 双链表的说明 1.1 双链表 - 创建 1.2 双链表 - 根据索引查找节点 1.3 双链表 - 根据索引插入节点 1.4 双链表 - 头插节点 1.5 双链表 - 尾插 1.6 双链表 - 根据索引来…...

电脑如何截屏?一起来揭晓答案!

在数字时代&#xff0c;截屏已经成为我们日常生活和工作中的必备技能。无论是为了捕捉有趣的网络瞬间&#xff0c;保存重要信息&#xff0c;还是为了协作和教育&#xff0c;电脑截屏都是一个强大而方便的工具。本文将介绍三种电脑如何截屏的方法&#xff0c;以满足各种需求&…...

【实战-08】flink 消费kafka自定义序列化

目的 让从kafka消费出来的数据&#xff0c;直接就转换成我们的对象 mvn pom <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information …...

深入浅出 Django 异步编程

随着 Web 应用对性能的要求日益提高&#xff0c;异步编程成为了提升响应速度、提高系统吞吐量的重要手段。Django 作为一个成熟的 Python Web 框架&#xff0c;自 3.1 版本开始支持了异步编程。在本文中&#xff0c;我们将探讨 Django 异步编程的关键概念&#xff0c;并提供实际…...

力扣 138. 随机链表的复制

文章目录 1.解题思路2.代码实现 1.解题思路 在原先链表的每一个元素后面插入一个与前一个相同val的值的结点,然后由于是在原链表进行的操作&#xff0c;因此找每个random就变得很方便直接访问即可&#xff0c;此题目的精髓是cur1->randomp->random->next,看懂这串代码…...

STM32外部中断大问题

问题&#xff1a;一直进入中断&#xff0c;没有触发信号&#xff0c;也一直进入。 描述&#xff1a;开PA0为外部中断&#xff0c;刚刚很好&#xff0c;一个触发信号一个中断&#xff0c;中断函数没有丢&#xff0c;也没有抢跑&#xff0c;开PA1为外部中断也是&#xff0c;都很好…...

FPGA配置采集AR0135工业相机,提供2套工程源码和技术支持

目录 1、前言免责声明 2、AR0135工业相机简介3、我这里已有的 FPGA 图像处理解决方案4、设计思路框架AR0135配置和采集图像缓存视频输出 5、vivado工程1–>Kintex7开发板工程6、vivado工程1–>Zynq7100开发板工程7、上板调试验证8、福利&#xff1a;工程代码的获取 1、前…...

KubeSphere v3.4.0 部署K8S Docker + Prometheus + grafana

KubeSphere v3.4.0 部署K8S 1、整体思路2、修改linux主机名3、 离线安装3.1 问题列表3.2 执行命令成功列表 1、整体思路 将KubeSphere v3.4.0 安装包传输到其中一台机器修改Linux主机名&#xff08;选取3台&#xff0c;修改为master01、master02、master03&#xff09;安装官方…...

Codeforces Round 908 (Div. 2)题解

目录 A. Secret Sport 题目分析: B. Two Out of Three 题目分析: C. Anonymous Informant 题目分析: A. Secret Sport 题目分析: A,B一共打n场比赛&#xff0c;输入一个字符串由A和‘B’组成代表A赢或者B赢&#xff08;无平局&#xff09;&#xff0c;因为题目说明这个人…...

Redis笔记 Redis主从同步

文章目录 Redis主从搭建主从架构主从数据同步原理全量同步增量同步repl_backlog原理 主从同步优化小结 Redis主从 搭建主从架构 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。 主从数据…...

数据结构-Prim算法构造无向图的最小生成树

引子&#xff1a; 无向图如果是一个网&#xff0c;那么它的所有的生成树中必有一颗生成树的边的权值之和是最小的&#xff0c;我们称 这颗权值和最小的树为&#xff1a;“最小生成树”&#xff08;MST&#xff09;。 其中&#xff0c;一棵树的代价就是树中所有权值之和。 而…...

MFC串口通信(SerialPort)

目录 1、SerialPort类的介绍和使用&#xff1a; &#xff08;1&#xff09;、SerialPort类的功能介绍 &#xff08;2&#xff09;、SerialPort类提供接口函数的介绍 1&#xff09;、InitPort函数 2&#xff09;、控制串口监视线程函数 3&#xff09;、获取事件&#xff0c…...

Vim基本使用操作

前言&#xff1a;作者也是初学Linux&#xff0c;可能总结的还不是很到位 Linux修炼功法&#xff1a;初阶功法 ♈️今日夜电波&#xff1a;美人鱼—林俊杰 0:21━━━━━━️&#x1f49f;──────── 4:14 …...

【深蓝学院】手写VIO第8章--相机与IMU时间戳同步--作业

0. 题目 1. T1 逆深度参数化时的特征匀速模型的重投影误差 参考常鑫助教的答案&#xff1a;思路是将i时刻的观测投到world系&#xff0c;再用j时刻pose和外参投到j时刻camera坐标系下&#xff0c;归一化得到预测的二维坐标&#xff08;这里忽略了camera的内参&#xff0c;逆深…...

Naocs配置中心配置映射List、Map、Map嵌套List等方式

一、配置映射List 1、常规逐个配置方式,示例如下: 代码: @Data @Configuration @ConfigurationProperties(prefix = "list-json-str") public class ConfListByJsonStr implements Serializable, InitializingBean {@ApiModelProperty("映射结果集")…...

如何通过CRM系统进行销售机会管理?

销售机会管理是在销售过程中对潜在客户的精细化管理&#xff0c;销售机会管理的本质是公司用于管理销售机会通用的工具和方法。对于希望建立长期客户关系的现代销售团队来说&#xff0c;CRM客户管理系统是必不可少的工具。那企业如何通过CRM系统进行销售机会管理&#xff1f; …...

解决idea启动tomcat控制台中文乱码

#1.tomcat日志中文乱码# 如图这种情况&#xff0c;一般在idea用tomcat跑一个web项目启动后tomcat日志在控制台打印出来会出现中文乱码的情况 解决方案1&#xff1a;tomcat的日志配置文件的编码修改&#xff0c;找到tomcat安装目录conf下的logging.properties&#xff0c;encod…...

vscode + cmake + opencv example

nice try on macos CMakeLists.txt cmake_minimum_required(VERSION 3.20) #添加OPENCV库 #指定OpenCV版本&#xff0c;代码如下 #find_package(OpenCV 3.3 REQUIRED) #如果不需要指定OpenCV版本&#xff0c;代码如下 find_package(OpenCV REQUIRED)#添加OpenCV头文件 includ…...

day57【动态规划】647.回文子串 516.最长回文子序列

文章目录 647. 回文子串516.最长回文子序列 647. 回文子串 力扣题目链接 代码随想录讲解 题意&#xff1a;给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的…...

分享vmware和Oracle VM VirtualBox虚拟机的区别,简述哪一个更适合我?

VMware和Oracle VM VirtualBox虚拟机的区别主要体现在以下几个方面&#xff1a; 首先两种软件的安装使用教程如下&#xff1a; 1&#xff1a;VMware ESXI 安装使用教程 2&#xff1a;Oracle VM VirtualBox安装使用教程 商业模式&#xff1a;VMware是一家商业公司&#xff0c;而…...

如何快速上手Atmosphere大气层:Switch开源自定义固件终极指南

如何快速上手Atmosphere大气层&#xff1a;Switch开源自定义固件终极指南 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable Atmosphere大气层是任天堂Switch游戏机的开源自定义固件解决方案&…...

如何用BilibiliDown打造个人专属B站音乐库:5步实现高品质音频自由

如何用BilibiliDown打造个人专属B站音乐库&#xff1a;5步实现高品质音频自由 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/g…...

创业团队如何利用Taotoken统一管理多个AI项目的API密钥与访问

创业团队如何利用Taotoken统一管理多个AI项目的API密钥与访问 1. 多项目密钥管理的常见挑战 小型创业团队在同时推进多个AI项目时&#xff0c;通常会面临模型API密钥管理的复杂性。每个项目可能使用不同的大模型服务&#xff0c;开发成员需要单独申请和管理各自的API密钥。这…...

Umi-OCR:如何通过开源OCR工具实现高效批量文字识别与自动化处理?

Umi-OCR&#xff1a;如何通过开源OCR工具实现高效批量文字识别与自动化处理&#xff1f; 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片&#xff0c;PDF文档识别&#xff0c;排除水印/页眉页脚&#xff0c;扫描/生…...

为什么你需要novel-downloader:打造个人数字图书馆的终极解决方案

为什么你需要novel-downloader&#xff1a;打造个人数字图书馆的终极解决方案 【免费下载链接】novel-downloader 一个可扩展的通用型小说下载器。 项目地址: https://gitcode.com/gh_mirrors/no/novel-downloader 你是否曾经遇到过这样的情况&#xff1f;深夜追更的小说…...

为 Hermes Agent 配置 Taotoken 作为自定义模型提供商

为 Hermes Agent 配置 Taotoken 作为自定义模型提供商 1. 准备工作 在开始配置前&#xff0c;请确保已安装 Hermes Agent 并获取有效的 Taotoken API Key。登录 Taotoken 控制台&#xff0c;在「API 密钥」页面创建新密钥或使用现有密钥。同时&#xff0c;在「模型广场」页面…...

为内部知识库问答系统接入Taotoken实现智能检索增强

为内部知识库问答系统接入Taotoken实现智能检索增强 1. 知识库智能检索的技术需求 企业内部知识库系统通常面临文档量大、检索效率低、自然语言理解能力不足等问题。传统关键词匹配方式难以准确理解员工提出的复杂问题&#xff0c;导致大量有价值的知识无法被有效利用。通过集…...

python google docstring

## 关于Python Google Docstring的一些想法 说实话&#xff0c;我接触Google Docstring这个命名规范也有好些年头了。刚开始觉得不就是个注释嘛&#xff0c;后来才发现这东西藏着挺多门道的。 先说说Docstring到底是什么。简单讲&#xff0c;它就是在Python函数、类或者模块开头…...

3步解锁锐龙处理器隐藏性能:RyzenAdj电源管理工具完全指南

3步解锁锐龙处理器隐藏性能&#xff1a;RyzenAdj电源管理工具完全指南 【免费下载链接】RyzenAdj Adjust power management settings for Ryzen APUs 项目地址: https://gitcode.com/gh_mirrors/ry/RyzenAdj 你是否觉得自己的AMD锐龙笔记本电脑续航时间太短&#xff1f;…...

告别臃肿模拟器:如何在Windows上轻松安装APK文件

告别臃肿模拟器&#xff1a;如何在Windows上轻松安装APK文件 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经想要在Windows电脑上运行安卓应用&#xff0c;却…...