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

【数据结构】数组和字符串(十一):字符串的定义与存储(顺序存储、链式存储及其C语言实现)

文章目录

  • 4.3 字符串
    • 4.3.1 字符串的定义与存储
      • 1. 顺序存储
      • 2. 链式存储
      • 3. C语言实现顺序存储
      • 4. C语言实现链式存储
        • 代码优化

4.3 字符串

  字符串(String)是由零个或多个字符(char)顺序排列组成的有限序列,简称为串。例如 “good morning”就是由12个字符构成的一个字符串。一般把字符串记作:

S = ′ ′ a 0 a 1 … a n − 1 ′ ′ S=''a_{0} a_{1}…a_{n-1}'' S=′′a0a1an1′′

  其中S是串名,引号中的字符序列是串值。字符个数是串的长度,长度为0的串被称为空串,因为它不包含任何字符。需要注意的是,空格字符(" ")并不是空串,因为它包含一个字符——空格。
  若把某个串称为主串,则主串中任意个连续的字符组成的子序列被称为子串。子串在主串中第一次出现时,其首字符在主串中的序号被称为该子串在主串中的位置。

4.3.1 字符串的定义与存储

  字符串在许多非数值计算问题中扮演着重要的角色,并在模式匹配、程序编译和数据处理等领域得到广泛应用。
  在高级程序设计语言中,字符串通常被定义为以特殊字符’\0’(称为空字符或字符串结束符)结尾的字符序列。这个约定使得在处理字符串时可以方便地确定字符串的结束位置。

  关于字符串的存储方式,主要有两种常见的方式:

  • 顺序存储:字符串的字符按照顺序依次存储在连续的内存空间中。这种方式使得字符串的访问和操作效率较高,可以通过索引直接访问任意位置的字符。在顺序存储方式中,字符串的长度可以通过计算字符个数或者遇到’\0’结束符来确定。

  • 链式存储:字符串的字符通过链表的方式进行存储。每个节点包含一个字符和指向下一个节点的指针。链式存储方式可以动态地分配内存,适用于长度可变的字符串。但是相比于顺序存储,链式存储方式需要更多的内存空间,并且访问字符需要遍历链表。

  选择何种存储方式取决于具体的应用场景和需求。顺序存储适合于需要频繁访问和操作字符串的情况,而链式存储适合于长度可变的字符串或者对内存空间要求较高的情况。关于字符串的基础知识亦可参考前文:
【重拾C语言】六、批量数据组织(三)数组初值;字符串、字符数组、字符串数组;类型定义 typedef
【重拾C语言】七、指针(三)指针与字符串(字符串与字符串数组;指针与字符串的遍历、拷贝、比较;反转字符串)

1. 顺序存储

  串的顺序存储是把一个串所包含的字符序列相继存入连续的字节中,通常用数组实现。例如字符串S="student", 顺序存储在数组A[10]中,则A[0]=‘s’,A[1]=‘t’,…,A[6]=‘t’ .

2. 链式存储

  串的链式存储是通过将可用的存储空间划分为一系列大小相同的节点来实现的。每个节点包含两个部分:一个存储字符的数据域和一个指向下一个节点的指针域。
  例如,假设我们有一个字符串S = “student”,我们可以使用链式存储方式将其表示为一个节点序列。每个节点包含一个字符和一个指向下一个节点的指针。
  链式存储的节点结构可以如下表示:

struct Node {char data;      // 存储字符的数据域Node* next;     // 指向下一个节点的指针域
};

  对于字符串S = “student”,可以创建以下节点序列:

Node 1: data = 's', next -> Node 2
Node 2: data = 't', next -> Node 3
Node 3: data = 'u', next -> Node 4
Node 4: data = 'd', next -> Node 5
Node 5: data = 'e', next -> Node 6
Node 6: data = 'n', next -> Node 7
Node 7: data = 't', next -> NULL

  其中,每个节点的data域存储一个字符,next指针指向下一个节点。最后一个节点的next指针为空(NULL),表示链表的结束。

  链式存储方式可以动态地分配内存空间,适用于长度可变的字符串。通过遍历链表,我们可以访问和操作字符串中的字符。然而,相对于顺序存储方式,链式存储需要额外的指针空间,并且访问字符的效率较低。

3. C语言实现顺序存储

#include <stdio.h>int main() {char S[] = "student";printf("String S: %s\n", S);return 0;
}

输出结果为:

String S: student

  使用字符数组S来存储字符串"student"。该字符串被存储在数组中的连续内存空间中,每个字符占据一个数组元素的位置。

4. C语言实现链式存储

  接下来,让我们使用C语言实现字符串的链式存储:我们将使用一个结构体来表示链表的节点,每个节点包含一个字符和一个指向下一个节点的指针。

#include <stdio.h>
#include <stdlib.h>struct Node {char data;struct Node* next;
};void printString(struct Node* head) {struct Node* current = head;while (current != NULL) {printf("%c", current->data);current = current->next;}printf("\n");
}int main() {struct Node* head = (struct Node*)malloc(sizeof(struct Node));struct Node* second = (struct Node*)malloc(sizeof(struct Node));struct Node* third = (struct Node*)malloc(sizeof(struct Node));struct Node* fourth = (struct Node*)malloc(sizeof(struct Node));struct Node* fifth = (struct Node*)malloc(sizeof(struct Node));struct Node* sixth = (struct Node*)malloc(sizeof(struct Node));struct Node* seventh = (struct Node*)malloc(sizeof(struct Node));head->data = 's';head->next = second;second->data = 't';second->next = third;third->data = 'u';third->next = fourth;fourth->data = 'd';fourth->next = fifth;fifth->data = 'e';fifth->next = sixth;sixth->data = 'n';sixth->next = seventh;seventh->data = 't';seventh->next = NULL;printf("String S: ");printString(head);return 0;
}

输出结果为:

String S: student

  创建一个链表来表示字符串"student"。每个节点都包含一个字符和一个指向下一个节点的指针。通过遍历链表,我们可以打印出链表中存储的字符,从而得到字符串的内容。注意,在实际应用中,我们应该在使用完链表后释放分配的内存,以避免内存泄漏。

代码优化
#include <stdio.h>
#include <stdlib.h>struct Node {char data;struct Node* next;
};void printString(struct Node* node) {while (node != NULL) {printf("%c", node->data);node = node->next;}
}int main() {struct Node* head = NULL;struct Node* tail = NULL;char characters[] = {'s', 't', 'u', 'd', 'e', 'n', 't'};int length = sizeof(characters) / sizeof(characters[0]);for (int i = 0; i < length; i++) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));newNode->data = characters[i];newNode->next = NULL;if (head == NULL) {head = newNode;tail = newNode;} else {tail->next = newNode;tail = newNode;}}printf("String S: ");printString(head);printf("\n");// 释放链表节点的内存struct Node* current = head;while (current != NULL) {struct Node* temp = current;current = current->next;free(temp);}return 0;
}

在这里插入图片描述

相关文章:

【数据结构】数组和字符串(十一):字符串的定义与存储(顺序存储、链式存储及其C语言实现)

文章目录 4.3 字符串4.3.1 字符串的定义与存储1. 顺序存储2. 链式存储3. C语言实现顺序存储4. C语言实现链式存储代码优化 4.3 字符串 字符串(String)是由零个或多个字符(char)顺序排列组成的有限序列&#xff0c;简称为串。例如 “good morning”就是由12个字符构成的一个字符…...

zk-Bench:SNARKs性能对比评估工具

1. 引言 JENS ERNSTBERGER等人2023年论文《zk-Bench: A Toolset for Comparative Evaluation and Performance Benchmarking of SNARKs》。 zk-Bench&#xff0c;定位为&#xff1a; 定位为首个公钥密码学性能评估基准测试框架和工具&#xff0c;重点关注通用ZKP系统的实测评…...

【Linux】NTP服务器配置、时间修改

查看当前系统时间date修改当前系统时间date -s "2018-2-22 19:10:30"查看硬件时间hwclock --show修改硬件时间hwclock --set --date "2018-2-22 19:10:30"同步系统时间和硬件时间hwclock --hctosys保存时钟clock –w1.设置NTP Server服务检查系统是否安装n…...

毕业设计基于SpringMVC+Mybatis+Bootstrap的电影院管理系统源码+数据库

<<电影院管理系统>> 电影院管理系统&#xff1a;SpringMVCJSPTomcatMybatisBootstrapJqueryAnimateCSSLayerJS 项目部署&#xff1a;该项目是IDEA版本&#xff0c;Maven项目 前端依赖&#xff1a; Bootstrap-3.4.1Animate.css- 4.1.1Jquery-3.6.0Layer-v3.5.1B…...

vantUI(Tabbar标签页)浏览器返回上一页的失效问题

在开发中遇到这样一个问题&#xff0c;由页面1切换到页面2&#xff0c;再点击浏览器的回退&#xff0c;无法回退到页面1。 开始以为是路由配置的有问题&#xff0c;但是子页面可以正常回退&#xff0c;因为replace只是替换路由&#xff0c;而不会往history栈中记录路由&#x…...

【算法】Prim算法(求最小生成树)

题目 给定一个 n 个点 m 条边的无向图&#xff0c;图中可能存在重边和自环&#xff0c;边权可能为负数。 求最小生成树的树边权重之和&#xff0c;如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G(V,E)&#xff0c;其中 V 表示图中点的集合&#xff0c;E…...

go语言,yaml实现简单的workflow工作流

目录 1.创建一个yaml文件&#xff0c;名字可以是student.yaml 2.创建go文件测试 3.执行结果 本文章内容&#xff0c;只是一个简单的案例&#xff0c;但足够映射到一个大的项目中。 工作流作用&#xff1a;工作流的作用就是通过yaml配置文件&#xff0c;将关于本工作流的一个…...

BaiduMallServcie

说明 本文档指导业务开发步骤 BaiduMallServcie 说明一. 登录业务1.1 数据库设计1.1.1 管理员表1.1.2 角色表1.1.3 关联表 管理员表与角色表关联1.1.4 权限表1.1.5 关联表 角色表与权限表关联1.1.6 管理员登录日志表1.1.7 查询权限示例1.2 添加用户一. 登录业务 1.1 数据库设…...

vue3+jsx+antd的插槽写法之一

如果在jsx里面直接这样按照官方的写法是会报错的 正确写法是&#xff1a;...

Shell 学习之 if 命令

1. 执行流程 在 Shell 脚本中&#xff0c;if 是一个 控制流语句&#xff0c;用于进行条件判断&#xff0c;根据条件的结果执行相应的操作。 # 首先&#xff0c;Shell 会检查表达式 condition 返回的 boolean 值。 # 如果 condition 的值为真&#xff0c;则执行 then 代码块&a…...

android 同步 服务器 时间

要将 Android 设备与服务器同步时间&#xff0c;可以通过以下两种方式实现&#xff1a; NTP 协议同步时间 NTP&#xff08;Network Time Protocol&#xff09;是一种网络协议&#xff0c;用于同步计算机的时间。Android 设备可以使用 NTP 协议来同步服务器时间。 Android 应…...

10、电路综合-基于简化实频的宽带匹配电路设计方法

10、电路综合-基于简化实频的宽带匹配电路设计方法 网络综合和简化实频理论学习概述中的1-9介绍了SRFT的一些基本概念和实验方法&#xff0c;终于走到了SRFT的另一个究极用途&#xff0c;宽带匹配电路的设计。 1、之前的一些回顾与总结 之前也给出了一些电路综合的案例&…...

N-130基于springboot,vue校园社团管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatis-plus 本系…...

Syntax Error: TypeError: this.getOptions is not a function的解决(Vue)

报错信息&#xff1a; TypeError: this.getOptions is not a function 这个是在运行项目是遇到的问题 这个报错是类型错误&#xff0c;this.getOptions 不是一个函数 。这个错误一般就是less-loader库里的错误。 主要是less-loader版本太高&#xff0c;不兼容this.getOptions…...

使用 kube-downscaler 降低Kubernetes集群成本

新钛云服已累计为您分享772篇技术干货 介绍 Kube-downscaler 是一款开源工具&#xff0c;允许用户定义 Kubernetes 中 pod 资源自动缩减的时间。这有助于通过减少非高峰时段的资源使用量来降低基础设施成本。 在本文中&#xff0c;我们将详细介绍 kube-downscaler 的功能、安装…...

LeetCode热题100——哈希表

哈希表 1.两数之和2.字母异位词分组3.最长连续序列 1.两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。可以按任意顺序返回答案。 // 题解思路&#xff1a;使用哈…...

Kubeadm

目录 绪论&#xff1a;实验步骤 1、环境准备 2、所有节点安装docker 3、所有节点安装kubeadm&#xff0c;kubelet和kubectl 4、部署K8S集群 5、部署 Dashboard 6、安装Harbor私有仓库 master&#xff08;2C/4G&#xff0c;cpu核心数要求大于2&#xff09; 192.168.…...

【Overload游戏引擎细节分析】PBR材质Shader---完结篇

PBR基于物理的渲染可以实现更加真实的效果&#xff0c;其Shader值得分析一下。但PBR需要较多的基础知识&#xff0c;不适合不会OpenGL的朋友。 一、PBR理论 PBR指基于物理的渲染&#xff0c;其理论较多&#xff0c;需要的基础知识也较多&#xff0c;我在这就不再写一遍了&…...

C++设计模式_18_State 状态模式

State和Memento被归为“状态变化”模式。 文章目录 1. “状态变化”模式1.1 典型模式 2. 动机 (Motivation)3. 代码演示State 状态模式3.1 常规方式3.2 State 状态模式 4. 模式定义5. 结构( Structure )6. 要点总结7. 其他参考 1. “状态变化”模式 在组件构建过程中&#xf…...

详解final, abstract, interface关键字

一.final关键字 1.final关键字介绍 ——final关键字可以去修饰类、方法、属性和局部变量 2.final关键字的作用 1&#xff09;final修饰类&#xff0c;这个类不能被其他类继承 2&#xff09;final修饰方法&#xff0c;方法不能被重写 3&#xff09;final修饰属性&#xff0c;属…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...