详解顺序字符串

顺序字符串的定义及其特点

定义

顺序字符串是指将字符串中的字符按照它们在字符串中的顺序依次存储在连续的内存空间中的数据结构。顺序字符串通常使用字符数组来表示,其中每个字符占用一个字节,最后一个字符后面留有一个空位,用于表示字符串的结束符'\0'。

特点

  1. 顺序存储:字符串中的字符按照它们在字符串中的顺序依次存储在连续的内存空间中。
  2. 长度固定:字符串的长度是固定的,不能动态增长或缩小。
  3. 随机访问:可以通过下标访问字符串中的任意字符,实现随机访问。

顺序字符串的运算

初始化

首先为字符串分配内存空间,如果内存分配失败,就输出错误信息并返回错误码;如果内存分配成功,就设置字符串的最大长度为输入的max,当前长度为0,然后返回0表示初始化成功。

c 复制代码
/*初始化串*/
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;
	return 0;
}

从字符常量拷贝

这是一个复制字符串的函数。它接受两个参数:一个是目标字符串(S),另一个是源字符串(from)。如果源字符串的长度超过了目标字符串的最大长度,它会打印错误信息并返回错误码。否则,它会将源字符串复制到目标字符串,并在目标字符串的末尾添加一个空字符,以标示字符串的结束。最后,它会将目标字符串的长度设置为源字符串的长度,并返回0表示复制成功。

c 复制代码
/*从字符常量拷贝*/
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;
}

模式匹配

这个函数是在主字符串中查找子字符串的位置。如果找到了,就返回开始匹配的位置;如果没有找到,就返回-1。它遍历主字符串的每个字符,从位置0开始,直到位置m-nm是主字符串的长度,n是子字符串的长度)。在每个位置,它尝试匹配子字符串。如果子字符串的字符和主字符串在相同位置的字符匹配,且尚未遍历完子字符串,就继续匹配。如果匹配成功,就返回当前位置。如果遍历完整个主字符串都没有找到匹配,就返回-1。

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

	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;
		}
	}
	return -1;
}

字符串长度比较

  1. 首先比较两个字符串的长度。如果s1的长度小于s2的长度,函数返回-1。如果s1的长度大于s2的长度,函数返回1。
  2. 如果两个字符串的长度相等,函数会逐个字符比较两个字符串。如果发现任何一个字符不相等,函数就返回相应的结果(1或-1)。
  3. 如果所有字符都相等,说明两个字符串是相等的,函数返回0。
c 复制代码
//字符串长度比较
int sstring_compare(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;
}

串长

c 复制代码
//串长
int slength(sstring* str) {
    return str->len;
}

串的拼接

C 库函数 - strcat()

  1. 首先,函数检查s1s2的长度之和是否超过了s1的最大长度。如果超过了,那么就使用realloc函数来重新分配s1->data的内存空间,使其能够容纳两个字符串的总长度(包括一个额外的空间用于存储空字符)。
  2. 然后,使用C标准库中的strcat函数将s2->data连接到s1->data的末尾。
  3. 最后,更新s1->len以反映新的字符串长度。
c 复制代码
//串的拼接
void strcat_sstring(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;
}

顺序字符串的实现

完整代码

项目结构

bash 复制代码
    sstring.c
    sstring.h
    main.c

项目文件

main.c

c 复制代码
#include <stdio.h>
#include "sstring.h"



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

	int i = 0; 
	int m = 0;
	int n = 0;

	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~6):");
		scanf("%d",&cmd);
		switch(cmd){
			case 1:
				init(&S, 100);
				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(sstring_compare(&S,&sub) == 1)
				{
					printf("主串的长度大于子串的长度\n");
				}
				else if(sstring_compare(&S,&sub) == -1)
				{
					printf("主符串的长度小于子串的长度\n");
				}
				else if(sstring_compare(&S,&sub) == 0)
				{
					printf("两个字符串相等\n");
				}
				else 
				{
					printf("主串和子串的长度相等但字符不一样\n");
				}
				break;
			case 6:
				printf("主串:%s的长度为%d\n",str1,slength(&S));
				printf("子串:%s的长度为%d\n",str2,slength(&sub));
				break;
			case 7:
			    printf("主串打印:%s,",S.data);
			    printf("子串打印:%s\n",sub.data);
			    break;
			case 8:
			    strcat_sstring(&S, &sub);
			    printf("主串和子串的拼接:%s\n",S.data);
			    break;
			case 9:
			    printf("本程序为顺序栈的演示程序,由曾苗强设计开发。\n对该文章有疑问欢迎交流!\n");
		}
		
	}while(cmd!=0);
}

sstring.c

c 复制代码
/*
	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;
	return 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;

	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;
		}
	}
	return -1;
}


//字符串长度比较
int sstring_compare(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 slength(sstring* str) {
    return str->len;
}

//串的拼接
void strcat_sstring(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;
}

sstring.h

c 复制代码
/*
	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 sstrmatch(sstring *S, sstring *sub);

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

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

//串的拼接
void strcat_sstring(sstring* s1, sstring* s2);

运行结果

小结

顺序字符串是一种常见的数据结构,它使用字符数组来存储字符串,并使用一个整数变量来记录字符串的长度。这种数据结构具有以下特点:

  1. 顺序存储:顺序字符串按照字符在内存中连续存储。
  2. 随机访问:通过下标访问和修改顺序字符串中的任意字符是高效的,可以实现随机访问。
  3. 修改灵活:方便地进行字符串的拼接、插入和删除等操作。
  4. 输入输出方便:顺序字符串可以通过标准输入输出函数(如scanf和printf)进行输出。

总之,顺序字符串是一种简单、灵活、实用的数据结构,适用于各种需要处理文本数据的应用场景。

参考文献

文心一言

相关推荐
yuanbenshidiaos15 分钟前
C++----------函数的调用机制
java·c++·算法
唐叔在学习19 分钟前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA38 分钟前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo40 分钟前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc1 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
游是水里的游2 小时前
【算法day20】回溯:子集与全排列问题
算法
yoyobravery2 小时前
c语言大一期末复习
c语言·开发语言·算法
Jiude2 小时前
算法题题解记录——双变量问题的 “枚举右,维护左”
python·算法·面试
被AI抢饭碗的人2 小时前
算法题(13):异或变换
算法
nuyoah♂3 小时前
DAY36|动态规划Part04|LeetCode:1049. 最后一块石头的重量 II、494. 目标和、474.一和零
算法·leetcode·动态规划