串的基本内容

本文详细介绍了字符串(串)的定义,以及定长顺序存储和变长分配存储两种主要的存储方式,包括代码实现。此外,还涵盖了串的基本操作如字符串比较、长度获取、拼接、子串定位等,并提到了KMP算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.串的定义和实现

1.1 串的定义

1.2 串的存储方式

1.2.1 定长顺序存储表示(详细介绍+代码实现)

1.2.2 变长分配储存表示(详细介绍+代码实现)

1.3 串的基本操作

1.3.1 StrCmp(S,T)  比较两个字符串的长度

1.3.2 StrLen(S)  字符串的长度

1.3.3 Strcat(S1,S2)  拼接两个字符串

1.3.5 Index(S,T) 子串定位


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]);  
}



未完待更

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值