数据结构 - C/C++ - 串

字符处理

C

  • 特性

    • C语言中字符串存储在字符数组中,以空字符'\0'结束。

    • 字符串常量,const char* str = "Hello",存储在只读的数据段中。

  • 布局

    • 字符串在内存中是字符连续存储的集合,最后一个字符为空字符(ASCII值为0),用来标识当前字符串的结束。

    • 字符串可以存储在栈(局部变量)、堆(动态分配)、全局、静态区等。

  • 处理

    • C标准库提供的字符串处理函数,<string.h>头文件中,包含了字符串拷贝、拼接、比较、长度、截断等。

CPP

  • 特性

    • C++提供了std::string类型,它封装了字符数组,并且在此基础上提供了更加丰富的字符串处理业务。

    • std::string支持内存动态扩容,不需要指定缓冲区大小。

  • 布局

    • std::string内部管理与维护一个动态分配内存大小的指针,用于存储字符串数据。
  • 处理

    • std::string是标准模板库(STL)中的一部分,其实现定义在头文件<string.h>中。

串的概念

  • 串基本概念

    • 串(字符串)是由零个或多个字符组成的有限序列。

  • 串和线程表

    • 线性表指的是元素之间的线性关系,元素之间的物理结构是次要的。

    • 串是特殊的线性表,串当中的元素为字符,串整体与字串的关系。

  • 串存储结构

    • 顺序结构

      • 顺序结构基于一段连续的内存空间来存储串当中的字符序列。
    • 链式结构

      • 链式结构基于链表的形式存储字符串,每个节点可以包含一个或多个字符。
    • 块链结构

      • 块链结构基于串的分割,每一块包含一个字符数组,不同的块通过链表关联。
         

串的操作

#include <iostream>namespace str
{// length       字符串长度// str          源字符串int length(const char* str){// 参数校验if (str == NULL) return -1;// 获取长度int nLength = 0;while (*(str++) != '\0') nLength++;// 返回结果return nLength;}// Assign       字符串赋值// Dest         目标字符串的缓冲区// Sour         源字符串// DestSize     目标缓冲区的大小void Assign(char* Dest, const char* Sour, size_t DestSize){// 参数校验if (Dest == NULL || Sour == NULL || DestSize == 0) return;// 内容赋值int nLength = 0;while (*Sour/*源字符串当前下标字符是否为空*/ && nLength < DestSize - 1/*目标缓冲区长度是否满足*/){//Dest[nLength] = Sour[nLength];*Dest++ = *Sour++;nLength++;}*Dest = '\0';}// Concatenate  字符串拼接// str1         第一个字符串的缓冲区// str2         连接的字符串缓冲区// str1Size     第一个字符串的缓冲区长度void Concatenate(char* str1, const char* str2, size_t str1Size){//参数校验if (str1 == NULL || str2 == NULL || str1Size == 0) return;//字符长度int str1length = str::length(str1);//字符拼接int i = 0;for (i = 0; str2[i] != '\0' && str1Size - 1 > str1length + i; i++){str1[str1length + i] = str2[i];}//追加标记str1[str1length + i] = '\0';}// SunString    子串提取// Sour         源字符串数据// Dest         提取字符串空间// nDestSize    提取字符串容量 // nStart       提取字符串位置// nCount       提取字符串数量void SubString(const char* Sour, char* Dest, int nDestSize, int nStart, int nCount){//参数校验if (Sour == NULL || Dest == NULL || nDestSize == 0 || nCount == 0) return;//起始校验int nSourLength = str::length(Sour);if (nSourLength <= nStart || nStart < 0) return;//长度校验if (nCount < 0 || nCount > nSourLength - nStart) return;//空间校验if (nCount >= nDestSize) return;//提取子串int i = 0;for (i = 0; i < nCount; i++){Dest[i] = Sour[nStart + i];}//字符追加Dest[i] = '\0';}// SubPosition  子串查找// Sour         源字符串// Sub          子串内容int SubPosition(const char* Sour, const char* Sub){//参数校验if (Sour == NULL || Sub == NULL) return -1;//数据备份int nPosition = 0;const char* str_it;const char* sub_it;//算法定位for (str_it = Sour; *str_it != '\0'; str_it++){sub_it = Sub;//数据匹配if (*str_it == *sub_it){const char* str_temp = str_it;//匹配子串while (*str_temp && *sub_it && (*str_temp == *sub_it)){str_temp++, sub_it++;}if (*sub_it == '\0'){return nPosition;}}nPosition++;}return -1;}// Compare      字符串比较// str1         源字符串// str2         目标字符串int Compare(const char* str1, const char* str2){//参数校验if (str1 == NULL || str2 == NULL) return -1;//字符比较while (*str1 && *str2){if (*str1 == *str2){str1++;str2++;}else{break;}}return *str1 - *str2;}// Insert       字符串插入// str1         源字符串数据// str2         被插入字符串数据// nPos         插入位置索引// size_str1    源字符串缓冲区总大小void Insert(char* str1, const char* str2, int nPos, int size_str1){//参数校验if (str1 == NULL || str2 == NULL) return;//字符长度int str1len = str::length(str1);int str2len = str::length(str2);//下标越界if (nPos < 0 || nPos > str1len) return;//空间处理if (str1len + str2len + 1 > size_str1) return;//移动空间for (int i = str1len; i >= nPos; i--){str1[i + str2len] = str1[i];}//数据拷贝for (int i = 0; i < str2len; i++){str1[nPos + i] = str2[i];}}// Delete       字符串删除// str          源字符串数据// nPos         起始删除位置// nlength      删除字符长度void Delete(char* str, int nPos, int nlength){//参数校验if (str == NULL) return;//起始校验int strlen = str::length(str);if (nPos < 0 || nPos > strlen) return;//删除校验if (nlength < 0 || (nPos + nlength) > strlen) return;//位置修正char* Start = str + nPos;char* End = str + nPos + nlength;//数据删除while (*End){*Start++ = *End++;}*Start = '\0';}// Replace      字符串替换// str          源字符串数据// to_replace   被替换字符串// repalce      替换字符串// size_str     缓冲区长度void Replace(char* str, const char* to_replace, const char* repalce, int size_str){//参数校验if (str == NULL || to_replace == NULL || repalce == NULL) return;//子串定位int nPos = str::SubPosition(str, to_replace);if (nPos == -1)return;//空间判断int strlen = str::length(str);int torlen = str::length(to_replace);int replen = str::length(repalce);if (strlen - torlen + replen > size_str) return;//拷贝数据char* pTemp = (char*)malloc(size_str);if (pTemp == NULL)return;memset(pTemp, 0, size_str);//00 00 00 00 00 00 00 00 00 00 00 00 00memcpy(pTemp, str, nPos);//H E L 00 00 00 00 00 00 00 00 00 00memcpy(pTemp + nPos, repalce, replen);//H E L 0 x C C 00 00 00 00 00 00memcpy(pTemp + nPos + replen, str + nPos + torlen, strlen - torlen - nPos);//H E L 0 x C C H E L L O 0memcpy(str, pTemp, size_str);free(pTemp);}// Split        字符串分割// str          源字符串数据// chDelimiter  分隔符// outCount     子串数量char** Split(const char* str, char chDelimiter, int* outCount){//参数校验if (str == NULL) return NULL;//分割数量int nCount_Delimiter = 1;for (int i = 0; str[i] != '\0'; i++){if (str[i] == chDelimiter) ++nCount_Delimiter;}//写回数据*outCount = nCount_Delimiter;//分配空间char** strArr = (char**)malloc(nCount_Delimiter * sizeof(char*));if (!strArr) return NULL;memset(strArr, 0, nCount_Delimiter * sizeof(char*));//子串长度int i = 0;int j = 0;int nCount_Word = 0;for (i = 0, nCount_Word = 0; str[i] != '\0'; i++){if (str[i] != chDelimiter){nCount_Word++;}else{strArr[j++] = (char*)malloc(nCount_Word * sizeof(char) + 1);nCount_Word = 0;}       }strArr[j] = (char*)malloc(nCount_Word * sizeof(char) + 1);//拷贝数据for (i = 0, j = 0, nCount_Word = 0; str[i]; i++){if (str[i] != chDelimiter){strArr[j][nCount_Word++] = str[i];}else{strArr[j][nCount_Word++] = '\0';j++;nCount_Word = 0;}}strArr[j][nCount_Word++] = '\0';return strArr;}}int main()
{//字符长度const char szBuffer1[50] = "0xCC";int nLength = str::length(szBuffer1);//字符赋值char szBuffer2[4] = { 0 };str::Assign(szBuffer2, "Hello", sizeof(szBuffer2));//字符拼接char szBuffer3[50] = "Hello";str::Concatenate(szBuffer3, "World", sizeof(szBuffer3));//子串提取char szBuffer4[] = "Hello World";char szBuffer5[10] = { 0 };str::SubString(szBuffer4, szBuffer5, sizeof(szBuffer5), 6, 5);//子串查找char szBuffer8[] = "HELHELLHELLO";char szBuffer9[] = "HELLO";str::SubPosition(szBuffer8, szBuffer9);//字符比较char szBuffer6[] = "Hel";char szBuffer7[] = "Hel";str::Compare(szBuffer6, szBuffer7);//字符插入char szBuffer10[12] = "Hello";char szBuffer11[] = "0xCC";str::Insert(szBuffer10, szBuffer11, 1, sizeof(szBuffer10));//字符删除str::Delete(szBuffer10, 1, 4);//字符替换char szBuffer12[] = "HELHELLHELLO";char szBuffer13[] = "HELL";char szBuffer14[] = "CC";   str::Replace(szBuffer12, szBuffer13, szBuffer14, sizeof(szBuffer12));//字符分割int nCount = 0;char szBuffer15[] = "Hello,World,Ferry,0xCC";char** resule = str::Split(szBuffer15, ',', &nCount);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/39424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

opencascade AIS_InteractiveContext源码学习7 debug visualization

AIS_InteractiveContext 前言 交互上下文&#xff08;Interactive Context&#xff09;允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是&#xff0c;对于已经被交互上下文识别的交互对象&#xff0c;必须使用上下文方法进行…

【问题已解决】Vue管理后台,点击登录按钮,会发起两次网络请求(竟然是vscode Compile Hero编译插件导致的)

问题 VueElement UI 做的管理后台&#xff0c;点击登录按钮&#xff0c;发现 接口会连续掉两次&#xff0c;发起两次网络请求&#xff0c;但其他接口都是正常调用的&#xff0c;没有这个问题&#xff0c;并且登录按钮也加了loading&#xff0c;防止重复点击&#xff0c;于是开…

搜索引擎常用语法

引号 (" "): 用双引号将词组括起来&#xff0c;搜索引擎将返回包含完全相同短语的结果。 示例&#xff1a;"人工智能发展趋势" 减号 (-): 在关键词前加上减号可以排除包含特定词语的结果。 示例&#xff1a;人工智能 -机器学习&#xff08;排除包含 “机器…

朴素贝叶斯解密:sklearn中的分类器工作原理

&#x1f4da; 朴素贝叶斯解密&#xff1a;sklearn中的分类器工作原理 在机器学习领域&#xff0c;朴素贝叶斯分类器因其简单、高效而广受欢迎。特别是在处理大量特征数据时&#xff0c;朴素贝叶斯表现出了卓越的性能。scikit-learn&#xff08;简称sklearn&#xff09;是Pyth…

JavaMySQL 学习(基础)

目录 Java CMD Java发展 计算机存储规则 Java学习 switch新用法&#xff08;可以当做if来使用&#xff09; 数组定义 随机数 Java内存分配 MySQL MySQL概述 启动和停止 客户端连接 数据模型 关系型数据库 SQL SQL通用语法 SQL分类 DDL--数据定义语言 数据库…

浏览器开发者工具辅助爬虫开发

文章目录 浏览器开发者工具辅助爬虫开发打开开发者工具使用Network面板分析请求数据示例步骤&#xff1a; 使用Elements面板查看和修改DOM结构示例步骤&#xff1a; 使用Console面板调试JavaScript代码示例步骤&#xff1a;示例代码&#xff1a;1. 输出日志信息2. 输出对象信息…

Vue 与 React 区别

Vue.js和React是现代Web开发中两种非常流行的前端框架&#xff0c;两者在**核心概念、组件以及生态系统扩展性**等方面存在区别。具体分析如下&#xff1a; 1. **核心概念** - **Vue**&#xff1a;Vue是一个渐进式JavaScript框架&#xff0c;它致力于视图层&#xff0c;易于上手…

左值右值, 左值引用右值引用,完美转发

一. 左值和右值 左值: 可以取地址的对象 右值: 不可以取地址的对象 double x1.0, y 2.0; 1; // 字面量, 不可取地址, 是右值 x y; // 表达式返回值, 不可取地址, 是右值 max(x, y); // 传值返回函数的返回值 (非引用返回)总结就是: 根据是否可以取地址来区分是左值还…

线程池666666

1. 作用 线程池内部维护了多个工作线程&#xff0c;每个工作线程都会去任务队列中拿取任务并执行&#xff0c;当执行完一个任务后不是马上销毁&#xff0c;而是继续保留执行其它任务。显然&#xff0c;线程池提高了多线程的复用率&#xff0c;减少了创建和销毁线程的时间。 2…

git修改已提交的commit注释

在Git中修改已经提交的commit注释通常有以下几种情况和相应的方法&#xff1a; 1. 修改最后一次提交的注释&#xff08;快速修正&#xff09; 如果你想要修改的是最后一次提交的注释&#xff0c;可以使用 --amend 选项&#xff1a; git commit --amend这个命令会将你的暂存区…

基于深度学习的光度检测

基于深度学习的光度检测&#xff08;Photometric Detection&#xff09;涉及从图像中检测和分析光照信息&#xff0c;用于多种应用&#xff0c;如场景理解、照明调节、增强现实&#xff08;AR&#xff09;、图像增强等。以下是关于这一领域的系统介绍&#xff1a; 1. 任务和目…

JAVA基础教程DAY1-类与方法及形参实参

首先经过C语言的学习&#xff0c;我们已经学会了基本的编程方法&#xff0c;我们知道C语言是面向过程的编程语言&#xff0c;而JAVA是面向对象的编程语言&#xff0c;所以接下来我们通过对比和举例来进行JAVA语言的学习 首先我们来讲类的概念 类&#xff1a;类是一个模板&…

Ubuntu开通5005端口 记录

Ubuntu版本&#xff1a;20.04 使用systemctl status firewalld查看防火墙状态&#xff0c;报错Unit firewalld.service could not be found 报错的原因是没有安装firewall&#xff0c;安装命令为sudo apt install firewalld&#xff0c;然后进行安装 安装完成后输入systemctl…

vscode jupyter选择Python环境时找不到我安装的Python

在一些情况下&#xff0c;我们需要自己安装一个Python&#xff0c;在选择内核是可能找不到指定的Python版本&#xff0c; 再次打开内核选择页面就能看到Python环境了 注意先到指定环境下安装依赖包&#xff1a; ./python3 pip install ipykernel notebook jupyter

人工智能-NLP简单知识汇总01

人工智能-NLP简单知识汇总01 1.1自然语言处理的基本概念 自然语言处理难点&#xff1a; 语音歧义句子切分歧义词义歧义结构歧义代指歧义省略歧义语用歧义 总而言之&#xff1a;&#xff01;&#xff01;语言无处不歧义 1.2自然语言处理的基本范式 1.2.1基于规则的方法 通…

[DataWhale大模型应用开发]学习笔记1-尝试搭建向量数据库

1.词向量 1.定义 词向量&#xff08;Word Vector&#xff09;是将单词表示为向量形式的技术&#xff0c;是自然语言处理&#xff08;NLP&#xff09;中的一种常用方法。通过将单词转化为向量&#xff0c;计算机能够更好地理解和处理语言。简单来说&#xff0c;词向量就是将单…

Windows系统安装NVM,实现Node.js多版本管理

目录 一、前言 二、NVM简介 三、准备工作 1、卸载Node 2、创建文件夹 四、下载NVM 五、安装NVM 六、使用NVM 1、NVM常用操作命令 2、查看NVM版本信息 3、查看Node.js版本列表&#xff1b; 4、下载指定版本Node.js 5、使用指定版本Node.js 6、查看已安装Node.js列…

深度学习赋能数据分析,联蔚盘云引领业务革新

一、引言 随着大数据时代的到来&#xff0c;深度学习技术正逐渐成为企业数据分析的新引擎。联蔚盘云凭借其在深度学习领域的深厚积累&#xff0c;为企业提供高效、精准的数据分析解决方案&#xff0c;助力企业实现业务革新与增长。 二、深度学习与数据分析的完美结合 联蔚盘…

【区块链+基础设施】国家健康医疗大数据科创平台 | FISCO BCOS应用案例

在医疗领域&#xff0c;疾病数据合法合规共享是亟待解决的难题。一方面&#xff0c;当一家医院对患者实施治疗后&#xff0c;若患者转到其 他医院就医&#xff0c;该医院就无法判断诊疗手段是否有效。另一方面&#xff0c;医疗数据属于个人敏感数据&#xff0c;一旦被泄露或被恶…

一个能让渲染性能提高100倍的办法

GPU 光线追踪是当今的热门话题&#xff0c;所以让我们来谈谈它&#xff01;今天我们将光线追踪一个单个球体。 使用片段着色器。 是的&#xff0c;我知道。并不特别花哨。你可以在 Shadertoy 上搜索并获得数百个示例(https://www.shadertoy.com/results?querysphere)。甚至已…