块状链表实现BigString大字符串操作(golang)
前言
块状链表是介于链表和数组之间的数据结构,能够在 O ( n ) O(\sqrt{n}) O(n)时间内完成插入、删除、访问操作。
数据结构如图所示。假设最大容量为 n n n, 则它有一个长度为 s = n s=\sqrt{n} s=n的链表。链表中每个结点是一个长度为 2 × n 2 \times \sqrt{n} 2×n的数组。
参考:https://oi-wiki.org/ds/block-list/
 
 实现时,有两个细节需要注意:
-  初始时,只有一个链表结点。随着数据越来越多,当某个结点内数组装满后,将分裂成两个结点。 
-  删除数据后,如果数据所在结点为空,则需要删除结点(链表首元结点不用删除)。 
本文以BigString为例进行实现。
实现
使用golang实现如下字符串功能:
- Append(str)向字符串尾部添加一个字符串
- Size()获取字符串长度
- Insert(index, char)向字符串某个位置插入一个字符
- Erase(index)删除某个位置的字符
- At(index)获了某个位置的字符
- Set(index, char)设置某个位置的字符
package mainimport ("fmt""math"
)type _Node struct {next *_Nodesize intdata []rune
}type BigString struct {head    *_Node // 没有哨兵,直接就是首元结点size    int    // 字符串大小bukSize int    // 分组大小maxSize int    // 最大字符大小
}func NewBigString(maxLen int) *BigString {if maxLen < 10 {maxLen = 10}// 计算分段长度s := int(math.Sqrt(float64(maxLen)))return &BigString{head:    &_Node{nil, 0, make([]rune, 2*s)},size:    0,bukSize: s,maxSize: maxLen,}
}func (this *BigString) String() string {var str stringfor node := this.head; node != nil; node = node.next {for i := 0; i < node.size; i++ {str += string(node.data[i])}}return str
}/*
*
在尾部插入字符
*/
func (this *BigString) Append(chars string) {for _, char := range chars {this.Insert(this.size, rune(char))}
}/*
*
在尾部插入字符
*/
func (this *BigString) Size() int {return this.size
}/*
*
在指定位置插入字符
*/
func (this *BigString) Insert(index int, char rune) {if this.size < this.maxSize && index >= 0 && index <= this.size {pos := -1for node := this.head; node != nil; node = node.next {if index <= node.size+pos+1 {insertPos := index - pos - 1 // 0 1 2 3 4 | 5 6 7   , index = 6,for j := node.size; j > insertPos; j-- {node.data[j] = node.data[j-1]}node.data[insertPos] = charnode.size++// 结点分裂开if node.size == len(node.data) {node2 := &_Node{node.next, this.bukSize, make([]rune, 2*this.bukSize)}for j := 0; j < this.bukSize; j++ {node2.data[j] = node.data[j+this.bukSize]}node.size -= this.bukSizenode.next = node2}break}pos += node.size}this.size++}
}/*
*
删除指定位置字符
*/
func (this *BigString) Erase(index int) {if index >= 0 && index < this.size {pos := -1var pre *_Node = nilfor node := this.head; node != nil; node = node.next {if index <= node.size+pos {deletePos := index - pos - 1for j := deletePos + 1; j < node.size; j++ {node.data[j-1] = node.data[j]}node.size--// 清理空结点if node.size == 0 {if node != this.head {pre.next = pre.next.next}}break}pos += node.sizepre = node}this.size--}
}/*
*
获取指定位置字符
*/
func (this *BigString) At(index int) rune {if index >= 0 && index < this.size {pos := -1for node := this.head; node != nil; node = node.next {if index <= node.size+pos {atPos := index - pos - 1return node.data[atPos]}pos += node.size}}return 0
}/*
*
设置指定位置字符
*/
func (this *BigString) Set(index int, char rune) {if index >= 0 && index < this.size {pos := -1for node := this.head; node != nil; node = node.next {if index <= node.size+pos {atPos := index - pos - 1node.data[atPos] = charbreak}pos += node.size}}
}测试
测试结果与测试代码如下。结果表明实现是正确的。

str := NewBigString(225)// 测试 Append, Insert, Stringfmt.Println("【测试 Append, Insert, String】")str.Append("hello world! my name is cloudea. this is my first big string implementation!\n")str.Append("世界 你好! 我的我名字是克劳迪亚。这是我的第一个大字符串实现哦!\n")fmt.Println(str)str.Insert(0, '*')str.Insert(78, '#')fmt.Println(str)for i := 0; i < 40; i++ {str.Insert(100, '$')}fmt.Println(str)// 测试Erasefmt.Println("【测试 Erase】")for i := 0; i < 40; i++ {str.Erase(100)}fmt.Println(str)// 测试测试At 和 Setfmt.Println("【测试At 和 Set】")str.Set(99, '你')str.Set(100, '呀')str.Set(101, 'd')str.Set(102, '二')str.Set(103, '个')for i := 0; i < str.Size(); i++ {fmt.Print(string(str.At(i)))}fmt.Println()
相关文章:
 
块状链表实现BigString大字符串操作(golang)
前言 块状链表是介于链表和数组之间的数据结构,能够在 O ( n ) O(\sqrt{n}) O(n )时间内完成插入、删除、访问操作。 数据结构如图所示。假设最大容量为 n n n, 则它有一个长度为 s n s\sqrt{n} sn 的链表。链表中每个结点是一个长度为 2 n 2 \times \sqrt{…...
项目问题记录(持续更新)
1.在 yarn install的时候报 error achrinza/node-ipc9.2.2: The engine "node" is incompatible with this module. Expected version "8 || 10 || 12 || 14 || 16 || 17". Got "20.1.0" error Found incompatible module.需要执行 yarn config…...
 
Linux的进程
目录 一、进程占用的内存资源 二、进程的系统环境 三、进程一直在切换 四、父进程和子进程 五、进程状态 六、查看进程 1.ps -ef 列出所有进程 2.ps -lax 列出所有进程 3.ps aux列出所有进程 4.树形列出所有进程 七、作业(用来查看管理进程) …...
 
与其焦虑被 AI 取代或猜测前端是否已死, 不如看看 vertical-align 扎实你的基础!!!
与其焦虑被 AI 取代或猜测前端是否已死, 不如看看 vertical-align 扎实你的基础!!! vertical-align 设置 display 值为 inline, inline-block 和 table-cell 的元素竖直对齐方式. 从 line-height: normal 究竟是多高说起 我们先来看一段代码, 分析一下为什么第二行的行高, 也就…...
路由、交换机、集线器、DNS服务器、广域网/局域网、端口、MTU
前言:网络名词术语解析(自行阅读扫盲),推荐大家去读户根勤的《网络是怎样连接的》 路由(route): 数据包从源地址到目的地址所经过的路径,由一系列路由节点组成。某个路由节点为数据包选择投递方向的选路过程。 路由器工作原理 路…...
 
在全志V851S开发板上进行屏幕触摸适配
1.修改屏幕驱动 从ft6236 (删掉,不要保留),改为下面的 路径:/home/wells/tina-v853-open/tina-v853-open/device/config/chips/v851s/configs/lizard/board.dts(注意路径,要设置为自己的实际路…...
字符串拷贝时的内存重叠问题
字符串拷贝时的内存重叠问题 1.什么是内存重叠 拷贝的目的地址在源地址的范围内,有重叠。 如在写程序的过程中,我们用到的strcpy这个拷贝函数,在这个函数中我们定义一个目的地址,一个源地址,在拷贝的过程中如果内存重…...
 
告别PPT手残党!这6款AI神器,让你秒变PPT王者!
如果你是一个PPT手残党,每每制作PPT总是让你焦头烂额,那么你一定需要这篇幽默拉风的推广文案! 我向你保证,这篇文案将帮助你发现6款AI自动生成PPT的神器,让你告别PPT手残党的身份,成为一名PPT王者。 无论…...
JVM配置与优化
参考: JVM内存分区及作用(JDK8) https://blog.csdn.net/BigBug_500/article/details/104734957 java 进程占用系统内存过高分析 https://blog.csdn.net/fxh13579/article/details/104754340 Java之jvm和线程的内存 https://blog.csdn.ne…...
 
电力系统储能调峰、调频模型研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
 
C++基础之类、对象一(类的定义,作用域、this指针)
目录 面向对象的编程 类的引入 简介 类的定义 简介 访问限定符 命名规则 封装 简介 类的作用域 类的大小及存储模型 this指针 简介 面向对象的编程 C与C语言不同,C是面向对象的编程,那么什么是面向对象的编程呢? C语言编程,规定…...
 
javaScript---设计模式-封装与对象
目录 1、封装对象时的设计模式 2、基本结构与应用示例 2.1 工厂模式 2.2 建造者模式 2.3 单例模式 封装的目的:①定义变量不会污染外部;②能作为一个模块调用;③遵循开闭原则。 好的封装(不可见、留接口):①…...
 
【消息中间件】kafka高性能设计之内存池
文章目录 前言实现创建内存池分配内存释放内存 总结 前言 Kafka的内存池是一个用于管理内存分配的缓存区域。它通过在内存上保留一块固定大小的内存池,用于分配消息缓存、批处理缓存等对象,以减少频繁调用内存分配函数的开销。 Kafka内存池的实现利用了…...
创建型模式——单例(singleton)
1. 模式说明 单例模式保证类只有一个实例;创建一个对象,当你创建第二个对象的时候,此时你获取到的是已经创建过的对象,而不是一个新的对象; 1.1 使用场景 共享资源的访问权限;任务的管理类;数…...
 
算法:迷宫问题
描述 定义一个二维数组 N*M ,如 5 5 数组下所示: int maze[5][5] { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或…...
 
聊聊并发编程的12种业务场景
前言 并发编程是一项非常重要的技术,无论在面试,还是工作中出现的频率非常高。 并发编程说白了就是多线程编程,但多线程一定比单线程效率更高? 答:不一定,要看具体业务场景。 毕竟如果使用了多线程&…...
 
MySQL执行顺序
MySQL执行顺序 MySQL语句的执行顺序也是在面试过程中经常问到的问题,并且熟悉执行顺序也有助于SQL语句的编写。 SELECT FROM JOIN ON WHERE GROUP BY HAVING ORDER BY LIMIT执行顺序如下: FROM ON JOIN WHERE GROUP BY # (开始使用别名) SUM # SUM等…...
 
引领真无线耳机未来趋势,NANK南卡OE骨传导真无线耳机惊艳亮相
传统的蓝牙耳机存在很多问题,例如续航时间短、长期佩戴耳朵会不舒服,甚至影响听力等等。为了解决这些问题,在骨传导领域深耕十多年的南卡品牌推出了这款真无线骨传导耳机——NANK南卡 OE。 NANK南卡OE即将正式上线,这一消息一经宣…...
 
5款写作神器,帮助你写出5w+爆款文案,好用到哭
我不允许还有文案小白、新手博主不知道这5款写作利器! 每次一写文案就头秃的新媒体工作者,赶紧看过来吧!这5款好用到爆的写作神器,喝一杯咖啡的时间就能完成写作。 我和同事都是用它们,出了很多的爆款,现…...
 
相交链表问题
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意,函数返回结果后&…...
 
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
 
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
 
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
 
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
 
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
 
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
