字符串的详解-程序员宅基地

技术标签: 算法  数据结构  

一、字符串的定义

1.1字符串的定义

串是由零个或多个字符组成的有限序列,在计算机科学中是一种重要的数据类型。字符可以是字母、数字、符号等,对应于计算机中的编码。串可以用来表示文本、图像、音频等数据

1.2字符串的特点

串是由一系列字符组成的数据结构,具有以下特点:

  • 顺序性:串中的每个字符都有一个确定的位置,按照一定的次序排列。
  • 可变性:串的长度可以根据需要进行改变,可以动态地添加或删除字符。
  • 不可变性:一旦串被创建,其中的字符就不能被修改。
  • 常用操作:串的常用操作包括查找、插入、删除、替换、比较、拼接等。

二、字符串的定义实现与使用

2.1字符串的接口定义

typedef struct
{
	char* data;
	int max;
	int len;
}sstring;

/*初始化串*/
int init(sstring *S, int max);

/*字符拷贝*/
int sstrcpy(sstring *S, char* from);

/*模式匹配*/
int sstrmatch(sstring *S, sstring *sub);

//串比较
int sstrcmp(const sstring* s1, const sstring* s2);

//串长
int sstrlen(sstring* str);

//串的联接 
void sstrcat(sstring* s1, sstring* s2);

2.2字符串的实现

2.2.1字符串初始化
int init(sstring *S, int max)
{
	S->data = (char*)malloc(sizeof(char)*max);

	if(!S->data)
	{
		printf("申请内存失败!1000");
		return 1000;
	}
	S->max = max;
	S->len = 0;
}
2.2.2字符串拷贝
int sstrcpy(sstring *S, char* from)
{
	int i;
	int len = strlen(from);

	if(len>S->max)
	{
		printf("超出了字符串S的长度!1001\n");
		return 1001;
	}
	for(i=0;i<len;i++)
	{
		S->data[i] = from[i];
	}
	S->data[i] = '\0';
	S->len = len;
	return 0;
}
2.2.3字符串模式匹配
int sstrmatch(sstring *S, sstring *sub)
{
	int i, j, k;
	int m = S->len;
	int n = sub->len;

	if(S->len==0||sub->len==0){
		printf("字符串为空");
		return;
	} 

	for(i=0;i<=m-n;i++)
	{
		j=0;
		k=i;
		while(j<n && S->data[k] == sub->data[j])
		{
			j++;
			k++;
		}
		if(j==n)
		{
			return i+1;
		}
	}
	return -1;
}
2.2.4字符串比较
int sstrcmp(const sstring* s1, const sstring* s2)
{
    int i;
    int result;

    // 比较两个字符串的长度
    if (s1->len < s2->len) {
        return -1;
    } else if (s1->len > s2->len) {
        return 1;
    }

    // 长度相等,比较每个字符
    for (i = 0; i < s1->len; i++) {
        if (s1->data[i] < s2->data[i]) {
            return -1;
        } else if (s1->data[i] > s2->data[i]) {
            return 1;
        }
    }

    // 字符串相等
    return 0;
}
2.2.5字符串长度
int sstrlen(sstring* str) {
    return str->len;
}
2.2.5字符串拼接
void sstrcat(sstring* s1, sstring* s2) {
    if (s1->len + s2->len > s1->max) {
        s1->data = (char*)realloc(s1->data, (s1->len + s2->len + 1) * sizeof(char));
        s1->max = s1->len + s2->len + 1;
    }
    strcat(s1->data + s1->len, s2->data);
    s1->len += s2->len;
}

2.3字符串的使用

#include <stdio.h>
#include "sstring.h"
#include <stdlib.h>
#include "welcome.h"

int main(int argc, char* argv[])
{
	
	sstring S;
	sstring sub;
	int index;
	char str1[100];
	char str2[100];
	int cmd,i,m,n;

	int result;
	for(i=0;i<strlen(welcome);i++)
		{
			printf("%c",welcome[i]);
			for(m=0;m<1000;m++)
				for(n=0;n<1000;n++)
				{
					;
				}
		}

	printf("\n\n\n");

	do
	{	
		printf("-----------字符串演示-----------\n");
		printf(" 1. 初始化\n");
		printf(" 2. 输入串\n");
		printf(" 3. 从字符常量拷贝\n");
		printf(" 4. 模式匹配?\n");
		printf(" 5. 串比较\n");
		printf(" 6. 串长\n");
		printf(" 7. 输出串\n");
		printf(" 8. 串的拼接\n");
		printf(" 9. 帮助\n");
		printf(" 0. 退出\n");
		printf(" 请选择(0~9):");
		scanf("%d",&cmd);
		switch(cmd){
		case 1:
			init(&S, 1000);
			init(&sub, 100);
			printf("初始化成功!\n");
			break;
		case 2:
			printf("请输入主串:");
			scanf("%s", str1);
			printf("请输入子串:");
			scanf("%s", str2);
			break;
		case 3:
			sstrcpy(&S, &str1);
			sstrcpy(&sub, &str2);
			printf("从字符复制完成!\n");
			break;
		case 4:
			index = sstrmatch(&S,&sub);
			if(index>=0)
			{
				printf("匹配成功,子串在主串的%d位置\n", index); 
			}
			else
			{
				printf("子串不在主串种!\n");
			}
			break;
		case 5:
			if(sstrcmp(&S,&sub) == 1){
				printf("主串的长度大于子串的长度\n");
			}else if(sstrcmp(&S,&sub) == -1){
				printf("主串的长度小于子串的长度\n");
			}
			else if(sstrcmp(&S,&sub) == 0){
				printf("两个字符串相等\n");
			}
			break;
		case 6:
			printf("主串:%s的长度为%d\n",str1,sstrlen(&S));
			printf("子串:%s的长度为%d\n",str2,sstrlen(&sub));
			break;
		case 7:
		    printf("主串打印:%s",S.data);
		    printf("子串打印:%s\n",sub.data);
		    break;
		case 8:
		    sstrcat(&S, &sub);
		    printf("主串和子串的拼接:%s\n",S.data);	
		    break;
		case 9:
		    printf("本程序为字符串的演示程序,由黄彬森设计开发!\n");
		    break;
		}
		
	}while(cmd!=0);
}

三、完整代码

3.1 main.c文件代码

#include <stdio.h>
#include "sstring.h"
#include <stdlib.h>
#include "welcome.h"

int main(int argc, char* argv[])
{
	
	sstring S;
	sstring sub;
	int index;
	char str1[100];
	char str2[100];
	int cmd,i,m,n;

	int result;
	for(i=0;i<strlen(welcome);i++)
		{
			printf("%c",welcome[i]);
			for(m=0;m<1000;m++)
				for(n=0;n<1000;n++)
				{
					;
				}
		}

	printf("\n\n\n");

	do
	{	
		printf("-----------字符串演示-----------\n");
		printf(" 1. 初始化\n");
		printf(" 2. 输入串\n");
		printf(" 3. 从字符常量拷贝\n");
		printf(" 4. 模式匹配?\n");
		printf(" 5. 串比较\n");
		printf(" 6. 串长\n");
		printf(" 7. 输出串\n");
		printf(" 8. 串的拼接\n");
		printf(" 9. 帮助\n");
		printf(" 0. 退出\n");
		printf(" 请选择(0~9):");
		scanf("%d",&cmd);
		switch(cmd){
		case 1:
			init(&S, 1000);
			init(&sub, 100);
			printf("初始化成功!\n");
			break;
		case 2:
			printf("请输入主串:");
			scanf("%s", str1);
			printf("请输入子串:");
			scanf("%s", str2);
			break;
		case 3:
			sstrcpy(&S, &str1);
			sstrcpy(&sub, &str2);
			printf("从字符复制完成!\n");
			break;
		case 4:
			index = sstrmatch(&S,&sub);
			if(index>=0)
			{
				printf("匹配成功,子串在主串的%d位置\n", index); 
			}
			else
			{
				printf("子串不在主串种!\n");
			}
			break;
		case 5:
			if(sstrcmp(&S,&sub) == 1){
				printf("主串的长度大于子串的长度\n");
			}else if(sstrcmp(&S,&sub) == -1){
				printf("主串的长度小于子串的长度\n");
			}
			else if(sstrcmp(&S,&sub) == 0){
				printf("两个字符串相等\n");
			}
			break;
		case 6:
			printf("主串:%s的长度为%d\n",str1,sstrlen(&S));
			printf("子串:%s的长度为%d\n",str2,sstrlen(&sub));
			break;
		case 7:
		    printf("主串打印:%s",S.data);
		    printf("子串打印:%s\n",sub.data);
		    break;
		case 8:
		    sstrcat(&S, &sub);
		    printf("主串和子串的拼接:%s\n",S.data);	
		    break;
		case 9:
		    printf("本程序为字符串的演示程序,由黄彬森设计开发!\n");
		    break;
		}
		
	}while(cmd!=0);
}

3.2  sstring.c文件代码

#include "sstring.h"


/*初始化串*/
int init(sstring *S, int max)
{
	S->data = (char*)malloc(sizeof(char)*max);

	if(!S->data)
	{
		printf("申请内存失败!1000");
		return 1000;
	}
	S->max = max;
	S->len = 0;
}


/*字符拷贝*/
int sstrcpy(sstring *S, char* from)
{
	int i;
	int len = strlen(from);

	if(len>S->max)
	{
		printf("超出了字符串S的长度!1001\n");
		return 1001;
	}
	for(i=0;i<len;i++)
	{
		S->data[i] = from[i];
	}
	S->data[i] = '\0';
	S->len = len;
	return 0;
}


/*模式匹配*/
int sstrmatch(sstring *S, sstring *sub)
{
	int i, j, k;
	int m = S->len;
	int n = sub->len;

	if(S->len==0||sub->len==0){
		printf("字符串为空");
		return;
	} 

	for(i=0;i<=m-n;i++)
	{
		j=0;
		k=i;
		while(j<n && S->data[k] == sub->data[j])
		{
			j++;
			k++;
		}
		if(j==n)
		{
			return i+1;
		}
	}
	return -1;
}


//串比较
int strcmp(const sstring* s1, const sstring* s2)
{
    int i;
    int result;

    // 比较两个字符串的长度
    if (s1->len < s2->len) {
        return -1;
    } else if (s1->len > s2->len) {
        return 1;
    }

    // 长度相等,比较每个字符
    for (i = 0; i < s1->len; i++) {
        if (s1->data[i] < s2->data[i]) {
            return -1;
        } else if (s1->data[i] > s2->data[i]) {
            return 1;
        }
    }

    // 字符串相等
    return 0;
}

//串长
int sstrlen(sstring* str) {
    return str->len;
}

//串的拼接
void sstrcat(sstring* s1, sstring* s2) {
    if (s1->len + s2->len > s1->max) {
        s1->data = (char*)realloc(s1->data, (s1->len + s2->len + 1) * sizeof(char));
        s1->max = s1->len + s2->len + 1;
    }
    strcat(s1->data + s1->len, s2->data);
    s1->len += s2->len;
}

3.2  sstring.h文件代码

typedef struct
{
	char* data;
	int max;
	int len;
}sstring;

/*初始化串*/
int init(sstring *S, int max);

/*字符拷贝*/
int sstrcpy(sstring *S, char* from);

/*模式匹配*/
int sstrmatch(sstring *S, sstring *sub);

//串比较
int sstrcmp(const sstring* s1, const sstring* s2);

//串长
int sstrlen(sstring* str);

//串的联接 
void sstrcat(sstring* s1, sstring* s2);

3.4  welcome.h文件代码

char welcome[] = "\n\
|     .-.\n\ 
|    /   、         .-.\n\
|   /     、       /   、       .-.     .-.\n\
+--/-------、-----/-----、-----/---、---/---、---/-、-/-、/、/---\n\
| /         、   /       、   /     '-'     '-'              \n\
|/           '-'         '-'                               \n\
";

四、代码运行结果


|     .-.
|    /   、         .-.
|   /     、       /   、       .-.     .-.
+--/-------、-----/-----、-----/---、---/---、---/-、-/-、/、/---
| /         、   /       、   /     '-'     '-'
|/           '-'         '-'



-----------字符串演示-----------
 1. 初始化
 2. 输入串
 3. 从字符常量拷贝
 4. 模式匹配?
 5. 串比较
 6. 串长
 7. 输出串
 8. 串的拼接
 9. 帮助
 0. 退出
 请选择(0~9):1
初始化成功!
-----------字符串演示-----------
 1. 初始化
 2. 输入串
 3. 从字符常量拷贝
 4. 模式匹配?
 5. 串比较
 6. 串长
 7. 输出串
 8. 串的拼接
 9. 帮助
 0. 退出
 请选择(0~9):2
请输入主串:aaaa
请输入子串:bbb
-----------字符串演示-----------
 1. 初始化
 2. 输入串
 3. 从字符常量拷贝
 4. 模式匹配?
 5. 串比较
 6. 串长
 7. 输出串
 8. 串的拼接
 9. 帮助
 0. 退出
 请选择(0~9):3
从字符复制完成!
-----------字符串演示-----------
 1. 初始化
 2. 输入串
 3. 从字符常量拷贝
 4. 模式匹配?
 5. 串比较
 6. 串长
 7. 输出串
 8. 串的拼接
 9. 帮助
 0. 退出
 请选择(0~9):5
主串的长度大于子串的长度
-----------字符串演示-----------
 1. 初始化
 2. 输入串
 3. 从字符常量拷贝
 4. 模式匹配?
 5. 串比较
 6. 串长
 7. 输出串
 8. 串的拼接
 9. 帮助
 0. 退出
 请选择(0~9):6
主串:aaaa的长度为4
子串:bbb的长度为3
-----------字符串演示-----------
 1. 初始化
 2. 输入串
 3. 从字符常量拷贝
 4. 模式匹配?
 5. 串比较
 6. 串长
 7. 输出串
 8. 串的拼接
 9. 帮助
 0. 退出
 请选择(0~9):8
主串和子串的拼接:aaaabbb
-----------字符串演示-----------
 1. 初始化
 2. 输入串
 3. 从字符常量拷贝
 4. 模式匹配?
 5. 串比较
 6. 串长
 7. 输出串
 8. 串的拼接
 9. 帮助
 0. 退出
 请选择(0~9):7
主串打印:aaaabbb子串打印:bbb
-----------字符串演示-----------
 1. 初始化
 2. 输入串
 3. 从字符常量拷贝
 4. 模式匹配?
 5. 串比较
 6. 串长
 7. 输出串
 8. 串的拼接
 9. 帮助
 0. 退出
 请选择(0~9):4
匹配成功,子串在主串的5位置
-----------字符串演示-----------
 1. 初始化
 2. 输入串
 3. 从字符常量拷贝
 4. 模式匹配?
 5. 串比较
 6. 串长
 7. 输出串
 8. 串的拼接
 9. 帮助
 0. 退出
 请选择(0~9):9
本程序为字符串的演示程序,由黄彬森设计开发!
-----------字符串演示-----------
 1. 初始化
 2. 输入串
 3. 从字符常量拷贝
 4. 模式匹配?
 5. 串比较
 6. 串长
 7. 输出串
 8. 串的拼接
 9. 帮助
 0. 退出
 请选择(0~9):0

--------------------------------
Process exited after 59.68 seconds with return value 0
请按任意键继续. . .

五、小结

字符串是由0个或者多个字符组成的有限序列,一般用来表示文本,图像等的数据。

字符串基本操作如:

        串的长度:串中字符的个数,常用len(s)表示。

        串的比较:可以按字典序比较两个串的大小,常用==!=<><=>=等运算符进行比较。

        串的子串:串中任意连续的一段字符,可以通过s[i:j]表示,其中i是子串的起始位置,j是子串的终止位置+1。

        串的连接:将两个串连接在一起形成一个新的串,常用s1+s2表示。

        串的复制:将一个串复制n次形成一个新的串,常用s*n表示。

        串的查找:在一个串中查找某个子串的位置。

六、参考文献

【1】CSDN

【2】数据结构(C语言)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_54938554/article/details/134153105

智能推荐

各种“网络地球仪”-程序员宅基地

文章浏览阅读4.5k次。Weather Globe(Mackiev)Google Earth(Google)Virtual Earth(Microsoft)World Wind(NASA)Skyline Globe(Skylinesoft)ArcGISExplorer(ESRI)国内LTEarth(灵图)、GeoGlobe(吉奥)、EV-Globe(国遥新天地) 软件名称: 3D Weather Globe(http:/_网络地球仪

程序员的办公桌上,都出现过哪些神奇的玩意儿 ~_程序员展示刀,产品经理展示枪-程序员宅基地

文章浏览阅读1.9w次,点赞113次,收藏57次。我要买这些东西,然后震惊整个办公室_程序员展示刀,产品经理展示枪

霍尔信号、编码器信号与电机转向-程序员宅基地

文章浏览阅读1.6w次,点赞7次,收藏63次。霍尔信号、编码器信号与电机转向从电机出轴方向看去,电机轴逆时针转动,霍尔信号的序列为编码器信号的序列为将霍尔信号按照H3 H2 H1的顺序组成三位二进制数,则霍尔信号翻译成状态为以120°放置霍尔为例如不给电机加电,使用示波器测量三个霍尔信号和电机三相反电动势,按照上面所说的方向用手转动电机得到下图① H1的上升沿对应电机q轴与H1位置电角度夹角为0°,..._霍尔信号

个人微信淘宝客返利机器人搭建教程_怎么自己制作返利机器人-程序员宅基地

文章浏览阅读7.1k次,点赞5次,收藏36次。个人微信淘宝客返利机器人搭建一篇教程全搞定天猫淘宝有优惠券和返利,仅天猫淘宝每年返利几十亿,你知道么?技巧分享:在天猫淘宝京东拼多多上挑选好产品后,按住标题文字后“复制链接”,把复制的淘口令或链接发给机器人,复制机器人返回优惠券口令或链接,再打开天猫或淘宝就能领取优惠券啦下面教你如何搭建一个类似阿可查券返利机器人搭建查券返利机器人前提条件1、注册微信公众号(订阅号、服务号皆可)2、开通阿里妈妈、京东联盟、拼多多联盟一、注册微信公众号https://mp.weixin.qq.com/cgi-b_怎么自己制作返利机器人

【团队技术知识分享 一】技术分享规范指南-程序员宅基地

文章浏览阅读2.1k次,点赞2次,收藏5次。技术分享时应秉持的基本原则:应有团队和个人、奉献者(统筹人)的概念,同时匹配团队激励、个人激励和最佳奉献者激励;团队应该打开工作内容边界,成员应该来自各内容方向;评分标准不应该过于模糊,否则没有意义,应由客观的基础分值以及分团队的主观综合结论得出。应有心愿单激励机制,促进大家共同聚焦到感兴趣的事情上;选题应有规范和框架,具体到某个小类,这样收获才有目标性,发布分享主题时大家才能快速判断是否是自己感兴趣的;流程和分享的模版应该有固定范式,避免随意的格式导致随意的内容,评分也应该部分参考于此;参会原则,应有_技术分享

自动化测试 ——自动卸载软件_msiexec.exe /x-程序员宅基地

文章浏览阅读1.3k次,点赞2次,收藏9次。在平常的测试工作中,经常要安装软件,卸载软件, 即繁琐又累。 安装和卸载完全可以做成自动化。 安装软件我们可以通过自动化框架,自动点击Next,来自动安装。 卸载软件我们可以通过msiexec命令行工具自动化卸载软件_msiexec.exe /x

随便推点

[Lua]table使用随笔-程序员宅基地

文章浏览阅读222次。table是lua中非常重要的一种类型,有必要对其多了解一些。

JAVA反射机制原理及应用和类加载详解-程序员宅基地

文章浏览阅读549次,点赞30次,收藏9次。我们前面学习都有一个概念,被private封装的资源只能类内部访问,外部是不行的,但这个规定被反射赤裸裸的打破了。反射就像一面镜子,它可以清楚看到类的完整结构信息,可以在运行时动态获取类的信息,创建对象以及调用对象的属性和方法。

Linux-LVM与磁盘配额-程序员宅基地

文章浏览阅读1.1k次,点赞35次,收藏12次。Logical Volume Manager,逻辑卷管理能够在保持现有数据不变的情况下动态调整磁盘容量,从而提高磁盘管理的灵活性/boot分区用于存放引导文件,不能基于LVM创建PV(物理卷):基于硬盘或分区设备创建而来,生成N多个PE,PE默认大小4M物理卷是LVM机制的基本存储设备,通常对应为一个普通分区或整个硬盘。创建物理卷时,会在分区或硬盘的头部创建一个保留区块,用于记录 LVM 的属性,并把存储空间分割成默认大小为 4MB 的基本单元(PE),从而构成物理卷。

车充产品UL2089安规测试项目介绍-程序员宅基地

文章浏览阅读379次,点赞7次,收藏10次。4、Dielecteic voltage-withstand test 介电耐压试验。1、Maximum output voltage test 输出电压试验。6、Resistance to crushing test 抗压碎试验。8、Push-back relief test 阻力缓解试验。7、Strain relief test 应变消除试验。2、Power input test 功率输入试验。3、Temperature test 高低温试验。5、Abnormal test 故障试验。

IMX6ULL系统移植篇-系统烧写原理说明_正点原子 imx6ull nand 烧录-程序员宅基地

文章浏览阅读535次。镜像烧写说明_正点原子 imx6ull nand 烧录

Gradle配置阿里云Maven镜像仓库地址_gradle 配置阿里镜像-程序员宅基地

文章浏览阅读1.8k次。搭建maven本地仓库参考博客_gradle 配置阿里镜像