一、串的定义
#define MAXLEN 101
typedef struct{
char ch[MAXLEN];
int len;
}SString;
二、串的操作
1、串的插入
在s的位置pos前插入t,串分三种情况:
- s有足够的空间,插入t后剩下的s串还能放下
s->len+t.len<=MAXLEN && pos+t.len<= MAXLEN
- s没有足够空间,只能容纳全部t,但是剩下的s串舍弃
s->len+t.len>MAXLEN && pos+t.len<=MAXLEN
- s没有足够空间,连t都不能完全存储完,所以存多少算多少
s->len+t.len>MAXLEN && pos+t.len>MAXLEN
int StrInsert(SString* s, int pos, SString t){
int i;
if(pos<0||pos>(s->len)) return 0;//位置不存在
//插入t后s还够用
if(s->len+t.len<=MAXLEN){
for(i=s->len+t.len-1;i>=pos+t.len;i--){
s->ch[i]=s->ch[i-t.len]; //把pos后的字符串移到后面
}
for(i=0;i<t.len;i++){
s->ch[pos+i]=t.ch[i]; //插入字符串t
}
s->len+=t.len; //更新s长度
}
//能插入t但是s空间不够
else if(s->len+t.len>MAXLEN){
if(pos+t.len<=MAXLEN){
for(i=MAXLEN-1;i>=pos+t.len;i--){
s->ch[i]=s->ch[i-t.len]; //移动pos后的,但是只能移动几个算几个
}
for(i=0;i<t.len;i++) s->ch[i+pos]=t.ch[i]; //插入字符串t
s->len=MAXLEN; //更新s长度
}
}
//连t都需要舍弃末尾了
else{
for(i=0;i<t.len;i++) s->ch[i+pos]=t.ch[i]; //存多少t算多少了
s->len=MAXLEN; //更新s长度
}
return 0;
}
2、串的删除
删除s中从pos位置起长度为len的串
int StrDelete(SString* s, int pos, int len){
int i;
if(pos<0||pos>(s->len-len)) return 0; //删除位置不合理
for(i=pos+len;i<s->len;i++) s->ch[i-len]=s->ch[i];
s->len-=len;
return 1;
}
3、串的复制
将t复制到s,记得判断是否溢出
int StrCopy(SString* s, SString* t){
int i;
if(s->len<t->len){
for(i=0;i<s->len;i++) s->ch[i]=t->ch[i];
}else{
for(i=0;i<t->len;i++) s->ch[i]=t->ch[i];
s->len=t->len;
}
return 0;
}
4、串的判空
int StrEmpty(SString s){
if(s.len==0) return 1;
else return 0;
}
5、返回串长
int StrLength(SString s){
return (s.len);
}
6、串的清空
int StrClear(SString* s){
s->len=0;
return 1;
}
7、串的连接
将t连接到s的后面,分三种情况:
- 连接后能放下
- s没达到MAXLEN,连t后会超出,舍弃t后面
- s达到了MAXLEN,不再连接t
int StrCat(SString* s, SString t){
int i;
if(s->len+t.len<=MAXLEN){
for(i=s->len;i;<s->len+t->len;i++) s->ch[i]=t.ch[i-s->len];
s->len+=t.len;
return 1;
}
//连接后超出MAXLEN
else if(s->len<MAXLEN){ //s未满 舍弃t的后面
for(i=s->len;i<MAXLEN;i++) s->ch[i]=t.ch[i-s->len];
s->len=MAXLEN;
return 0;
}
//其他情况即 s已经MAXLEN了,不再放t
return 0;
}
8、串的比较
比较s与t,如果s==t则返回0,s>t返回1,s<t返回-1
int StrCompare(SString s, SString t){
for(int i=0;i<s.len&&i<t.len;i++){
//按照字典序,有不同的则作差比较
if(s.ch[i]!=t.ch[i]) return (s.ch[i]-t.ch[i]);
//遍历完了某一个字符串,求长度差
return (s.len-t.len);
}
}
9、求子串函数
SubString(SString* sub, SString s, int pos, int len){
int i;
//清空sub字符串
if(sub->ch!=NULL) free(sub->ch);
if(pos<0||pos>s.len||len<1||len>s.len-pos){
sub->ch=NULL;
sub->len=0;
return 0;
}else{
sub->ch=(char*)malloc(len);
if(sub->ch==NULL) return 0;
for(i=0;i<len;i++) sub->ch[i]=s.ch[i+pos];
sub->len=len;
return 1;
}
}
10、定位函数
StrIndex(SString s, int pos, SString t){
if(s.len==0||t.len==0) return 0;
int i=pos; //定位s
j=0; //定位t
while(i<s.len&&j<t.len){
if(s.ch[i]==t.ch[j]){
i++; j++; //接着比对下一个
}else{
i=i+1-j; //注意这里!!!回到比较开始点的下一个!!!
j=0; //t从头开始
}
}
if(j>=t.len) return (i-j);
else return 0;
}
三、块链串
1、定义
#define BLOCK_SIZE 5
typedef struct Block{
char ch[BLOCK_SIZE];
struct Block *next;
}Block;
typedef struct{
Block *head;
Block *tail;
int len;
}BLString;
块
链
串
的
存
储
密
度
=
s
i
z
e
o
f
(
c
h
)
s
i
z
e
o
f
(
B
l
o
c
k
)
.
块链串的存储密度=\frac{sizeof(ch)}{sizeof(Block)}.
块链串的存储密度=sizeof(Block)sizeof(ch).
本文更新至2020.7.11