目录
1.串的定义和实现
1.1 串的定义
串:串是由零个或任意多个字符组成有限序列。一般记为:s="a1a2a3...an"(n>=0)
串可以是字母、数字或其他字符,n为串的长度。
1.2 串的存储方式
1.2.1 定长顺序存储表示(详细介绍+代码实现)
类似于线性表的顺序结构存储,用一组地址连续的存储单元存储串值的字符序列。在串定长顺序存储结构中,为每个串变量分配一个固定长度的存储区,即定长数组。
//定义存储结构--顺序存储
#include<stdio.h>
#include<stdlib.h>
#define maxsize 80
typedef char Elemtype;
typedef struct{
Elemtype date[maxsize];
int Len;
}String;
//将串进行初始化
String *init_string()
{
String *s;
s = (String*)malloc(sizeof(String));
if(s!=NULL){
s->Len=0;
}
return s;
}
//创造一个串并求其串长度
void createstring(String *s)
{
printf("请输入一段字符串,按回车结束:\n");
gets(s->date);
int i=0,j=0;
while(s->date[i]!='\0'){
i++;
j++;
}
s->Len = j;
}
//在主函数中实现调用
int main()
{
String *s1;
s1 = init_string();
createstring(s1);
printf("%s",s1->date);
return 0;
}
1.2.2 变长分配储存表示(详细介绍+代码实现)
变长分配存储表示(又叫动态分配存储表示)方法的特点是,在程序执行过程中根据需要动态分配。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义Str结构体
typedef struct {
char *ch; // 指向动态分配存储区首地址的字符指针
int length; // 长度
} Str;
// 初始化Str结构体,并为其分配存储空间
Str* initStr(const char *str) {
Str *s = (Str*)malloc(sizeof(Str));
if (s == NULL) {
printf("内存分配失败!\n");
return NULL;
}
s->length = strlen(str);
s->ch = (char*)malloc(s->length + 1); //为空终止符增加1
if (s->ch == NULL) {
printf("内存分配失败!\n");
free(s); // 如果字符数组分配失败,则释放Str结构体
return NULL;
}
strcpy(s->ch, str);
return s;
}
// 释放Str结构体所占用的存储空间
void freeStr(Str *s) {
if (s != NULL) {
free(s->ch);
free(s);
}
}
// 打印Str结构体内容
void printStr(Str *s) {
if (s != NULL) {
printf("String: %s\nLength: %d\n", s->ch, s->length);
} else {
printf("Str is NULL\n");
}
}
int main() {
// 初始化Str结构体
Str *myStr = initStr("Hello, World!");
// 打印Str结构体内容
printStr(myStr);
// 释放Str结构体所占用的存储空间
freeStr(myStr);
// 再次尝试打印(应该为空或错误)
printStr(myStr);
return 0;
}
1.2.3 块链存储表示
串的块链存储表示和线性表的链式存储结构相类似,也可采用链表方式存储串值。由于串结构的特殊性——结构中的每个数据元素是一个字符,则用链表存储串值时,存在一个“结点大小”的问题,即每个结点可以存放一个字符,也可以存放多个字符。当结点大小大于1时,由于串长不一定是结点大小的整数倍,则链表中的最后一个结点不一定被串值占满,此时通常补上“#”或其他的非串值字符(通常“#”不属于串的字符集,是一个特殊的符号)。
具体代码参考以下链接:
https://blog.youkuaiyun.com/weixin_44021971/article/details/128098875
1.3 串的基本操作
以下只举几个常用操作:(若想要了解其他可再自行搜索)
1.3.1 StrCmp(S,T) 比较两个字符串的长度
初始条件:串 S 和 T 存在。
操作结果:若S > T,则返回值 > 0;
若S = T,则返回值 = 0;
若S < T,则返回值 < 0。
例如:StrCmp(“data”, “state”) < 0
StrCmp(“cat”, “case”) > 0
1.3.2 StrLen(S) 字符串的长度
初始条件:串 S 存在。
操作结果:返回 S 的元素个数,称为串的长度。
1.3.3 Strcat(S1,S2) 拼接两个字符串
初始条件:串 S1 和 S2 存在。
操作结果:返回由 S1 和 S2 联接而成的新串
例如: Strcat( ''man'', ''kind'')
求得 S1 = ''mankind''
1.3.4 SubStr(S,i,j) 求从i个字符起,长度为j的子串
初始条件:串 S 存在,1 ≤ i ≤ StrLen (S) 且 0 ≤ j ≤ StrLen (S) - i + 1。
操作结果:返回串 S 的第 i 个字符起长度为 j 的子串。若 j = 0 得到的是空串。
例如:SubStr (''commander'',4,3) 求得:sub = ''man''
SubStr (''commander'',9,1) 求得: sub = ''r''
1.3.5 Index(S,T) 子串定位
初始条件:串S和T存在,T是非空串。
操作结果: 若主串 S 中存在和串 T 值相同的子串, 则返回它在主串 S 中第一次出现的位置,否则返回值为0。
例如:
子串在主串中的位置”意指子串中的第一个字符在主串中的位序。
假设 S = ''abcaabcaaabc '', T = ''bca''
Index(S, T) = 2;
1.3. 6 Replace( S, T ,V) 置换
初始条件:串 S, T 和 V 均已存在,且 T 是非空串。
操作结果:用 V 替换主串 S 中出现的所有与(模式串)T 相等的子串。
例如:
假设 S = ‘abcaabcaaabca’, T = 'bca '
若 V = 'x ', 则经置换后得到 S = 'axaxaax '
若 V = 'bc ', 则经置换后得到 S = 'abcabcaabc'
1.3.7 Insert (S, i, T)
初始条件:串S和T存在,1≤i≤StrLength(S)
操作结果:在串S的第i个字符之后插入串T。
例如:
S = 'chater ',T = 'rac ',则执行 Insert(S, 4, T) 之后得到 S = 'chatracer '
1.3.8 Delete (S, i, j)
初始条件:串S存在 1 ≤ i ≤ StrLen(S) - j + 1。
操作结果:从串S中删除第 i 个字符起长度为 j 的子串。
1.3.9 求子串
具体函数实现
int StrSub (char *t, char *s, int i, int len)
{ int slen; slen=StrLength(s);
if ( i<1 || i>slen || len<0 || len>slen-i+1)
{ printf("参数不对"); return 0; }
for (j=0; j<len; j++)
t[j]=s[i+j-1];
t[j]=’\0’;
return 1;}
1.3.10 串比较
若s1 == s2,操作返回值为 0;
若s1 < s2, 返回值 < 0;若 s1 > s2 , 返回值 > 0。
具体函数实现
int StrComp(char *s1, char *s2)
{ int i=0;
while (s1[i]= =s2[i] && s1[i]!=’\0’ &&s2[i]!=’\0’)
i++;
return (s1[i]-s2[i]);
}
未完待更