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

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

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

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

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

C++实现分布式网络通信框架RPC(2)——rpc发布端

有了上篇文章的项目的基本知识的了解&#xff0c;现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...

若依登录用户名和密码加密

/*** 获取公钥&#xff1a;前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...