在这里我们采用定长顺序存储表示(不知道也没关系)
在C语言中以’\0’表示串的终结,此时串长为隐藏值,不方便进行某些串操作。所以,这里我们用第一个数组来存储长度。
&表示引用不知道也没关系
StrAssign(&T,chars)
初始条件:char是字符串常量
操作结构:生成一个值为chars的串T
代码:
#include<stdio.h>
#include<stdlib.h>
#define MAXSTRLEN 100 //用户可在100以内定义最大长度
union SString //因为第一个数组存储长度的原因,这里使用了共用体
{ //有兴趣的小伙伴可以直接定义字符数组试试
int len;
char ch;
};
void StrAssign(union SString *T,char *chars)
{
int i=0;
while (*(chars+i) != '\0' && i<MAXSTRLEN)
{
T[i+1].ch = *(chars+i); //T[0]用于存储串的长度,所有T[i+1]
++i;
}
T[0].len = i; //i为整型,得用对应的类型存储,不然会很麻烦
}
int main()
{
union SString T[MAXSTRLEN+1]; //零单元存放串的长度
StrAssign(T,"hello world!");
for (int i=0;i<T[0].len;++i)
{
printf("%c",T[i+1].ch);
}
printf("\n串的长度为:%d",T[0].len);
return 0;
}
运行结果:
main函数中的是用来测试用的,下面将不再给出全部代码及运行结果,仅给出相关函数
StrCopy(&T,S)
初始条件:串S存在
操作结果:由串S复制得串T
代码:
void StrCopy(union SString *T,union SString *S)
{
for (int i=0;i<S[0].len && i<MAXSTRLEN;++i)
{
T[i+1].ch= S[i+1].ch; //一一修改
}
T[0].len = S[0].len; //更新串T的长度
}
StrEmpty(S)
初始条件:串S存在
操作结果:串S为空返回True(1) 否则false(0)
代码:
int StrEmpty(union SString *T)
{
if (T.len == 0) return 1;
return 0;
}
StrCompare(S,T)
初始条件: 串S,T均存在
操作结果:如果 S>T 返回值>0 如果S<T 返回值<0 否则返回值=0
代码:
int Strcompare(union SString *T,union SString *S)
{
for (int i=0;i<T[0].len && i<S[0].len;++i)
{
if (T[i+1].ch == S[i+1].ch) ++i; //相等则同时后移
else if (T[i+1].ch > S[i+1].ch) return 1; //T>S
else return 0; //T<S
}
}
StrLength(S)
初始条件:串S存在
操作结果:返回S的长度
代码:
int StrLength(union SString *T)
{
return T[0].len;
}
ClearString(&S)
初始条件:串S存在
操作结果:将串S清为空串
代码:
void ClearStr(union SString *T)
{
for (int i=0;i<T[0].len;++i)
{
T[i+1].ch = '\0';
}
T[0].len=0;
}
Concat(&T,S1,S2)
初始条件: 串S1,S2均存在存在
操作结果:用T返回由S1,S2连接而成的新串
代码:
void Concat(union SString *T,union SString *S1,union SString *S2)
{//T的值有三种情况
int i,label; //label用于标记
if (S1[0].len+S2[0].len <= MAXSTRLEN) //第一种情况 未截断
{
for (i=0;i<S1[0].len;++i) //复制S1
{
T[i+1].ch = S1[i+1].ch;
}
for (;i<S2[0].len;++i) //复制S2
{
T[i+1].ch = S2[i+1].ch;
}
T[0].len = S1[0].len+S2[0].len; //更新T的长度
label = 1;
}
else if (S1[0].len<MAXSTRLEN) //第二种情况 截断 (S1[0].len+S2[0].len > MAXSTRLEN)
{
for (i=0;i<S1[0].len;++i) //复制S1
{
T[i+1].ch = S1[i+1].ch;
}
for (;i<MAXSTRLEN;++i) //复制S2 条件和上一种情况不一样
{
T[i+1].ch = S2[i+1].ch;
}
T[0].len = MAXSTRLEN; //更新T的长度
label=0;
}
else //第三种情况 截断 (仅截取S1) (S1[0].len==MAXSTRLEN)
{
for (i=0;i<S1[0].len;++i) //复制S1
{
T[i+1].ch = S1[i+1].ch;
}
T[0].len = MAXSTRLEN; //更新T的长度
label=0;
}
return label;
}
SubString(&Sub,S,ps,length)
初始条件:串S存在,1<=pos<=StrLength(S) 且0<=length<=StrLength(S)-pos+1
操作结果:用Sub返回串S的第pos字符起长度为len的子串
代码:
void SubString(union SString *Sub,union SString *S,int pos,int length)
{
if (pos < 1 || pos > S[0].len || length < 0 || length >S[0].len-pos+1)
//说一下S[0].len-pos+1
//如有串’abcde’ pos=1 则5-pos=4 因为是从pos开始 故还要加上1
{
printf("请输入正确的值");
return;
}
for (int i=0;i<length;++i)
{
Sub[i+1].ch = S[pos-1+1+i].ch; //pos-1是为了对应下标,加1是因为第一个位置存储串的长度
}
Sub[0].len = len;
}
Index(S,T,pos)
初始条件:串S和T存在,T是非空串,1<=pos<=StrLength(S)
操作结果:返回子串T在主串S中第pos个字符之后第一次出现的位置,若不存在则返回数值0。
代码:
int Idex(union SString *T,union SString *S,int pos)
{
int i,j,label=0;
if (pos < 1 || pos > S[0].len)
{
printf("请输入正确的值");
return label;
}
for (i=pos-1;i<S[0].len;++i) //pos-1对应数组下标
{
j = i;
while (S[j+1].ch == T[j+1].ch && j<S[0].len && i-j<T[0].len)
{
j++;
}
if (j-i == T[0].len) //j-i为上一个循环执行的次数
{
label=i+1;
break;
}
}
return label;
}
StrInsert(&S,pos,T)
初始条件:串S,T均存在1<=pos<=StrLength(S)+1
操作结果:在串S的第pos个字符前插入串T
代码:
void StrInsert(union SString *S,int pos,union SString *T)
{
int i;
if (pos < 1 || pos > S[0].len+1)
{
printf("输入的值不合法!\n");
return;
}
for (i=S[0].len;i>=pos;--i) //未插入T而腾出空间
{
S[i+T[0].len].ch = S[i].ch;
}
for (i=pos;i-pos<T[0].len;++i) //插入
{
S[i].ch = T[i-pos+1].ch;
}
S[0].len+=T[0].len; //更新S的长度
}
StrDelete(&S,pos,len)
初始条件:串S存在1<=pos<=StrLength(S)-len+1
操作结果:删除串S的第pos字符起长度为len的子串
代码:
void StrDelete(union SString *S,int pos,int len)
{
int i;
if (pos < 1 || pos > S[0].len-len+1) //pos > S[0].len-len+1 即 len > S[0].len-pos+1
{ //两数相减得的是其距离,因为从pos起,所以+1
printf("输入的值不合法!\n");
return;
}
for (i=pos;i-pos<len;++i) //i-pos<len+1 让其循环len次;
{
S[i].ch = S[i+len].ch; //直接覆盖
}
S[0].len -= len;
}
DestroyString(&S)
初始条件:串S存在
操作结果:串S被销毁
代码:
用堆分配存储表示的时候再写