链式存储方式下字符串的replace(S,T1,T2)运算
链式存储方式下字符串的replace运算
- ⭐️题目
- ⭐️思路
- ⭐️代码
- ✨定义结点
- ✨打印字符串函数
- ✨计算字符串函数
- ✨初始化字符串函数
- ✨代码解读
- ✨字符串替换函数
- ✨字符串替换函数解读
- ✨ 主函数
- ✨完整代码
实现在链式存储下字符串的replace(S,T1,T2),来自课本习题的一道题目。这篇博客是我自己的思路,其中也还有很多不完善的地方,也还有很大的局限性。
希望对大家能有一点帮助。
⭐️题目
试编写一个函数,实现在链式存储方式下字符串的replace(S,T1,T2)运算。
⭐️思路
①首先,题目明确要求在链式存储方式下实现函数,所以,我们的字符串S以及我们的字符串T1,和要替换T1的字符串T2都必须是链式存储的。
明确了这一点,我们首先要初始化创建三个字符串,为了方便,写一个初始化字符串的函数。
②关于初始化一个字符串函数,采用前插或者尾插都可以。我自己写得是前插。
③关于替换掉S中T1,首先,应该是要找T1是否是在S中存在。其次应该计算T1的长度,改变有关两个结点的next值,举例即:

如上图,即改变b结点的next值,使之指向T2的头节点,并改变T2尾结点的next值,使之指向T1尾结点的后继结点。
我下面的代码并没有判断T1是否在S中是否存在,缺乏稳健性。计算T1的长度的原因是,这样以便我们能够很快找到f结点,并使T2的尾结点o指向f结点。
③关于替换,如上面所说,我们要找到关键结点。
即b结点、m结点和o结点。
b结点的找法是,当我们设置一个当前结点开始遍历循环S字符串时,也要找一个指针pre来跟踪cur指针,当cur指针指向T1的第一个字符时,这时q就指向了在了我们的目标结点。
f结点的查找方法是,我们计算T2结点的长度length,然后cur指针从当前c位置移动length-1个单位,这时cur就指向了f结点。
o结点即我们对T2字符串用指针tmp进行遍历,当以循环条件whiile(tmp->next)进行循环遍历,当不满足条件是,tmp恰好指在了尾结点即o结点。
④最后,我们改变相关结点的next值即可。
即pre->next=head2;,tmp->next=cur;
⑤释放T1.free(head1)
⭐️代码
✨定义结点
typedef struct node
{char data;struct node* next;
}linkstrnode;
✨打印字符串函数
void printstr(linkstrnode* head)
{linkstrnode* cur = head;while (cur){printf("%c", cur->data);cur = cur->next;}
}
✨计算字符串函数
int length(linkstrnode* head)
{int i = 0;linkstrnode* cur = head;while (cur){i++;cur = cur->next;}return i;
}
✨初始化字符串函数
linkstrnode* Initstr()
{int n,i;printf("请输入字符串的长度:\n");scanf("%d", &n);printf("请依次输入各节点:\n");getchar();//吸收回车linkstrnode* q = NULL;for (i = 1; i <= n; i++) {char s;scanf("%c",&s);//前插linkstrnode* newnode = (linkstrnode*)malloc(sizeof(linkstrnode));//产生新的结点newnode->data = s;newnode->next =q;q = newnode;}return q;
}
在这里插入一个在我自己写代码时的一个报错!0x00007FFC8C5325E7 (ucrtbased.dll)处(位于 DataStructure.exe 中)引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。 原因就是 使用了malloc函数 ,但没有包含<stdlib.h>头文件。
✨代码解读
①
首先,对于getchar()这一行
在下面的for循环中,用scanf来接收从键盘输入的字符。在上面,我们知道此时还有一个回车留在了缓冲区,如果不将缓冲区中的回车清除,那么scanf函数读取到的第一个字符就是回车了而不是从键盘输入的第一个字符。
②
在for循环中,scanf先从缓冲区读取到一个字符,然后我们用malloc函数在堆上开辟内存,开辟空间的大小即sizeof(linkstrnode),然后让栈上面的局部变量newnode来管理这块内存。
当我们开辟好空间,即开辟好一个结点的空间,我们就需要通过指针newnode来对这个结点进行赋值。newnode->data=s;即将scanf读取到的字符s赋值给newnode的data域。
那关键就在于next域,它就关键在可以将我们所输入的字符“连接起来”。
在这里我采用前插的方法。即我使一个字符所在的结点指向空。

然后此时,我存下来现在结点的值
q=newnode;
然后第二个结点如是,

然后最后一次的q即为这个链表的头节点。
✨字符串替换函数
//创建字符串替换函数
void strreplace(linkstrnode* head, linkstrnode *head1, linkstrnode* head2)
{linkstrnode* pre = NULL;linkstrnode* cur = head;linkstrnode* q;//q结点作为指向cur结点指针的前驱结点指针int i = 0;while (cur){if (cur->data == head1->data){while (i < length(head1) && cur){i++;cur = cur->next;}break;}else {pre = cur;cur = cur->next; }}//将T2替换原来T1的位置,插入到字符串S中//先找到T2的尾结点linkstrnode* tmp = head2;while (tmp->next){tmp = tmp->next;}pre->next = head2;tmp->next = cur;
}
✨字符串替换函数解读
head指向字符串S的头节点,head1是指向字符串T1的头节点,T2是指向字符串T2的头节点。
①
指针cur用来循环遍历S字符串。
❌❌我这里在S中查找T1字符串不严谨!只是判断了cur所指向的当前结点的值是否和T1头结点的值是否相等,就直接进行了替换。
当cur所指向结点的值和T1头节点的值不相等时,进入else条件体。

直到cur所指向结点的值和T1头节点的值相等。
若相等,则pre就指向了–>如图(假设d结点即是T1字串第一个结点的值)

这时,我们进入if条件体。我们需要的是,移动指针cur,使之指向T1尾结点值的后一个结点。(举例,若T1尾结点值为f,则我们需要将cur指向g)
这时,我们就需要直到T1的长度,使循环cur移动length-1次即可。
此时cur指向了–>如图
此时我们在循环中达到了目的,break退出循环即可。
②
下面,我们仍然是利用长度找到T2的尾结点。
③连接

即pre->next=head2;
tmp->next=cur;
✨ 主函数
int main()
{printf("*****创建字符串S*****\n");linkstrnode* head=Initstr();//创建指向字符串S头节点的指针printf("字符串S为:");printstr(head);printf("\n");printf("*****创建字符串T1*****\n");linkstrnode* head1 = Initstr();//创建指向字符串T1头节点的指针printf("字符串T1为:");printstr(head1);printf("\n");printf("*****创建字符串T2*****\n");linkstrnode* head2 = Initstr();//创建指向字符串T2头节点的指针printf("字符串T2为:");printstr(head2);printf("\n");strreplace(head, head1, head2);printf("被替换后的字符串S:");printstr(head);free(head1);//释放T1字符串所占的空间return 0;
}
✨完整代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<stdlib.h>//定义结点
typedef struct node
{char data;struct node* next;
}linkstrnode;//初始化链式字符串 (使用前插)
linkstrnode* Initstr()
{int n,i;printf("请输入字符串的长度:\n");scanf("%d", &n);printf("请依次输入各节点:\n");getchar();//吸收回车linkstrnode* q = NULL;for (i = 1; i <= n; i++) {char s;scanf("%c",&s);//前插linkstrnode* newnode = (linkstrnode*)malloc(sizeof(linkstrnode));//产生新的结点newnode->data = s;newnode->next =q;q = newnode;}return q;
}//打印字符串
void printstr(linkstrnode* head)
{linkstrnode* cur = head;while (cur){printf("%c", cur->data);cur = cur->next;}
}//计算字符串的长度
int length(linkstrnode* head)
{int i = 0;linkstrnode* cur = head;while (cur){i++;cur = cur->next;}return i;
}//创建字符串替换函数
void strreplace(linkstrnode* head, linkstrnode *head1, linkstrnode* head2)
{linkstrnode* pre = NULL;linkstrnode* cur = head;linkstrnode* q;//q结点作为指向cur结点指针的前驱结点指针int i = 0;while (cur){if (cur->data == head1->data){while (i < length(head1) && cur){i++;cur = cur->next;}break;}else {pre = cur;cur = cur->next; }}//将T2替换原来T1的位置,插入到字符串S中//先找到T2的尾结点linkstrnode* tmp = head2;while (tmp->next){tmp = tmp->next;}pre->next = head2;tmp->next = cur;}//主函数
int main()
{printf("*****创建字符串S*****\n");linkstrnode* head=Initstr();//创建指向字符串S头节点的指针printf("字符串S为:");printstr(head);printf("\n");printf("*****创建字符串T1*****\n");linkstrnode* head1 = Initstr();//创建指向字符串T1头节点的指针printf("字符串T1为:");printstr(head1);printf("\n");printf("*****创建字符串T2*****\n");linkstrnode* head2 = Initstr();//创建指向字符串T2头节点的指针printf("字符串T2为:");printstr(head2);printf("\n");strreplace(head, head1, head2);printf("被替换后的字符串S:");printstr(head);free(head1);return 0;
}相关文章:
链式存储方式下字符串的replace(S,T1,T2)运算
链式存储方式下字符串的replace运算 ⭐️题目⭐️思路⭐️代码✨定义结点✨打印字符串函数✨计算字符串函数✨初始化字符串函数✨代码解读✨字符串替换函数✨字符串替换函数解读✨ 主函数✨完整代码 实现在链式存储下字符串的replace(S,T1,T2),来自课本习题的一道题…...
unity脚本_Mathf和Math c#
首先创建一个脚本 当我们要做一个值趋近于一个值变化时 可以用Mathf.Lerp(start,end,time);方法实现 比如物体跟随...
轻量级仿 Spring Boot=嵌入式 Tomcat+Spring MVC
啥?Spring Boot 不用?——对。就只是使用 Spring MVC Embedded Tomcat,而不用 Boot。为啥?——因为 Boot 太重了:) 那是反智吗?Spring Boot 好好的就只是因为太重就不用?——稍安勿…...
笔记Kubernetes核心技术-之Controller
2、Controller 2.1、概述 在集群上管理和运行容器的对象,控制器(也称为:工作负载),Controller实际存在的,Pod是抽象的; 2.2、Pod和Controller关系 Pod是通过Controller实现应用运维,比如:弹…...
Azure云工作站上做Machine Learning模型开发 - 全流程演示
目录 本文内容先决条件从“笔记本”开始设置用于原型制作的新环境(可选)创建笔记本开发训练脚本迭代检查结果 关注TechLead,分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕࿰…...
前端 : 用html ,css,js写一个你画我猜的游戏
1.HTML: <body><div id "content"><div id "box1">计时器</div><div id"box"><div id "top"><div id "box-top-left">第几题:</div><div id "box…...
Illustrator 2024(AI v28.0)
Illustrator 2024是一款功能强大的矢量图形编辑软件,由Adobe公司开发。它是设计师、艺术家和创意专业人士的首选工具,用于创建和编辑各种矢量图形、插图、图标、标志和艺术作品。 以下是Adobe Illustrator的主要功能和特点: 矢量图形编辑&…...
【Git企业开发】第二节.Git 的分支管理
作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:Git企业级开发 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!࿰…...
第三章认识Node.js模块化开发
目录 认识Node.js 概述 作用 基本使用 Node.js的运行 Node.js的组成 Node.js的语法 Node.js全局对象 认识模块化开发 概述 场景 特点 模块成员的导入和导出 Node.js 模块化语法 导入模块 导出模块 ES6 模块化语法 导入模块 导出模块 项目 认识Node.js 概述…...
扩展Nginx的无限可能:掌握常见扩展模块和第三方插件的使用方法
Nginx是一款高性能的开源Web服务器和反向代理服务器。它具有模块化的架构,可以通过扩展模块和插件来增强其功能。在本文中,我将围绕Nginx的扩展模块和插件进行讲解,并提供一些常见的扩展模块和第三方插件的示例。 一、Nginx扩展模块 Nginx的…...
centos遇到的问题
lsof -i :8091 > 查看这个端口的线程 lsof : list open files 列出打开文件 -i : internet linux检测系统进程和服务: top : 实时监视系统的进程和资源的利用情况htop : top的增强版 问题: -bash: …...
本机spark 通idea连接Oracle的坑
1. 报错:Exception in thread "main" java.lang.NoSuchMethodError: scala.Product.$init$(Lscala/Product;)V 查询网上资料,是idea引入的scala运行环境版本与idea默认的scala版本不一样 也就是写的项目中的pom的spark版本与idea默认的版本不…...
网络协议--DNS:域名系统
14.1 引言 域名系统(DNS)是一种用于TCP/IP应用程序的分布式数据库,它提供主机名字和IP地址之间的转换及有关电子邮件的选路信息。这里提到的分布式是指在Internet上的单个站点不能拥有所有的信息。每个站点(如大学中的系、校园、…...
计算机视觉注意力机制小盘一波 (学习笔记)
将注意力的阶段大改分成了4个阶段 1.将深度神经网络与注意力机制相结合,代表性方法为RAM ⒉.明确预测判别性输入特征,代表性方法为STN 3.隐性且自适应地预测潜在的关键特征,代表方法为SENet 4.自注意力机制 通道注意力 在深度神经网络中…...
LVS+keepalive高可用集群
keepalive简介 keepalive为LVS应用延伸的高可用服务。lvs的调度器无法做高可用。但keepalive不是为lvs专门集群服务的,也可以为其他的的代理服务器做高可用。 keepalive在lvs的高可用集群,主调度器和备调度器(可以有多个) 一主两备或一主一备。 VRRP: k…...
Thread 和 Runnable 的区别
Thread 和 Runnable 接口的区别有四个: Thread 是一个类,Runnable 是接口,因为在 Java 语言里面的继承特性,接口可以支持多继承,而类只能单一继承。所以如果在已经存在继承关系的类里面要实现线程的话,只能…...
图神经网络和分子表征:5. Completeness
大家都知道 “两点确定一线,三点确定一平面”,那么多少个变量可以确定一个分子呢?这是最近顶刊们热烈讨论的话题。 (据笔者不完全统计)最早在 SphereNet (2022 ICLR)论文里,摘要上就…...
css-渐变色矩形
效果图: 代码: html: <!DOCTYPE html> <html><head><meta charset"utf-8"><meta name"viewport" content"initial-scale1.0, user-scalableno" /><title></title><link …...
使用easypoi-spring-boot-starter 4.1.1导入excel报错NoSuchMethodError和NoSuchMethodError
前言 使用easypoi进行excel的导入遇到的错误以及解决办法 easypoi项目地址:https://gitee.com/lemur/easypoi easypoi的Maven依赖: <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter<…...
matlab中类的分别之handle类和value类——matlab无法修改类属性值的可能原因
写在之前(吐槽) 最近由于变化了一些工作方向,开始需要使用matlab进行开发,哎哟喂,matlab使用的我想吐,那个matlab编辑器又没代码提示,又没彩色,我只好用vscode进行代码编辑…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
