#include<stdio.h>
#include<stdlib.h>
#include<string.h>//存储结构
#define MAXSIZE 255 //可以在255以内定义最大串长
typedef unsigned char SString[MAXSIZE + 1];//基本操作
void StrAssign(SString T, char *ch) //SString 本身已是一种指针,如果存储结构为结构体的话就要传指针的指针
{ //生成一个其值等于ch的串T
int i;
if(strlen(ch) > MAXSIZE)
{
exit(0);
}
else
{
T[0] = strlen(ch); //串的第一位存储串的长度
for( i = 1; i <= T[0]; i++ )
{
T[i] = *(ch + i - 1); //注意
}T[i] = '\0';
}
}void StrCopy(SString T,SString S)
{ //由串S复制得到串T
int i;
for(i = 0; i <= S[0]; ++i)
{
T[i] = S[i];
}
}int StrEmpty(SString T)
{ //串为空返回1,否则返回0
if( T[0] == 0 )
{
return 1;
}
else
{
return 0;
}
}int StrCompare( SString T, SString S)
{
int i;
for( i = 1; i <= T[0] && i <= S[0] ; ++i) //此处需从i=1开始,因为长度不是决定串大串小的关键因素
{
if(T[i] != S[i])
{
return T[i] - S[i]; //T > S,返回正数。反之返回负数。
}
} //只有当串长度内所有字符相同时,才能靠长度决定大小
return T[0] - S[0]; // T = S时,返回0. T > S,返回正数。反之返回负数。
}int StrLength(SString T)
{
return T[0];
}void ClearString(SString T) //将T清空为空串
{
T[0] = 0;
}void StrPrint(SString T)
{
int i;
for( i = 1; i <= T[0]; ++i)
{
printf("%c",T[i]);
}
printf("\n");
}void Concat(SString T, SString Sa, SString Sb) //两个串连接
{
int i ;
if(Sa[0] + Sb[0] <= MAXSIZE) //未截断
{
for( i = 1; i <= Sa[0]; ++i)
{
T[i] = Sa[i];
}
for( i = Sa[0] + 1; i <= Sa[0] + Sb[0]; ++i)
{
T[i] = Sb[i - Sa[0]];
}
T[0] = Sa[0] + Sb[0];
}
else //即是Sa[0] + Sb[0] > MAXSIZE, 有截断
{
if( Sa[0] < MAXSIZE ) //截断Sb的一部分
{
for(i = 1; i <= Sa[0]; ++i)
{
T[i] = Sa[i];
}
for(i = Sa[0] + 1; i <= MAXSIZE; ++i)
{
T[i] = Sb[i -Sa[0]];
}
T[0] = MAXSIZE;
}
else //仅取Sa(或者Sa的一部分)。Sa[0] >= MAXSIZE
{
for( i = 1; i <= MAXSIZE; ++i)
{
T[i] = Sa[i];
}
T[0] = MAXSIZE;
}
}
}void SubString(SString Sub, SString T, int pos,int len )
{ //用Sub返回串S的第pos个字符起长度为len的子串.
//1<=pos<=Strlength(T),且0<=len<=Strlength(S)-pos+1;
int i;
if( pos < 1 || pos > T[0] || len < 0 || len > T[0] - pos + 1) //T[0]表示有效字符数,而串的长度包括最后的结尾符
{ //len + pos > T[0] + 1,加1因为字符从第pos个起
exit(0);
}
for(i = 1; i <= len; ++i)
{
Sub[i] = T[pos + i - 1];
}
Sub[0] = len;
}int Index(SString T,SString S,int pos)
{ //返回子串S在主串T中第pos个字符之后第一次出现的位置。否则返回0;
int i,j;
if(0 < pos && pos <= T[0])
{
i = pos;
j = 1;
while(i <= T[0] && j <= S[0]) //可以利用StrCompare比较
{
//比较语句
if(T[i] == S[j])
{
++i;
++j;
}
else //指针后退,重新开始匹配
{
i = i - j + 2; //注意 i = i-j + 1 +1;最后的加1是因为j要跳到下一位置。
j = 1; //j=1表示第一个字符相同,因为可能子串只有部分与主串相同
}//跳出循环的条件
if( j > S[0])
{
return i - S[0]; //返回pos后第一次出现的位置
}
if( i > T[0])
{
return 0; //否则返回0
}
}
}
else
{
return 0; // 否则返回0
}
}
/*
int Index(SString T, SString S,int pos) //GOOD!
{
int i;
SString Sub;
if(0 < pos && pos <= T[0])
{
i = pos;
while( i < T[0] - S[0] + 1)
{
SubString(Sub,T,i,S[0]);
if(StrCompare(Sub,S) != 0)
{
++i;
}
else
{
return i;
}
}
}
return 0;
}
*/int StrInsert(SString T,int pos, SString S) //完全插入返回1,部分插入返回0
{ //在串T的第pos个字符之前插入串S
int i ;
if( pos < 1 && pos > T[0] + 1)
{
exit(0);
}
if(S[0] + T[0] <= MAXSIZE) //完全插入
{
for( i = T[0]; i >= pos ; --i)
{
T[i + S[0]] = T[i]; //原串后部分后移
}
for(i = pos; i < pos + S[0]; ++i)
{
T[i] = S[i - pos + 1];
}
T[0] += S[0];
}
else //部分插入 think about!
{
for( i = MAXSIZE; i >= pos + S[0]; --i)
{
T[i] = T[i - T[0]]; //注意画图,i-T[0]为能插入的S串部分
}
for( i = pos; i < pos + S[0] && i < MAXSIZE; i++)
{
T[i] = S[i - pos + 1];
}
T[0] = MAXSIZE;
}
}void StrDelete(SString S, int pos, int len)
{ //从串S中删除第pos个字符起长度为len的子串
int i;
if(pos < 1 || pos > S[0] - len + 1 || len < 0)
{
exit(0);
}
for( i = pos + len ; i <= S[0] ; ++i)
{
S[i-len] = S[i];
}
S[0] -= len;
}void Relace(SString S, SString T, SString V )
{ //初始条件:串S,T和V存在,T是非空串
//用V替换主串S中出现的所有与T相等的不重叠的子串
int i = 1; //串S的第一个字符起查找串T
if(StrEmpty(V))
{
exit(0);
}
do
{
i = Index(S,T,i); //结果i为从上一个i之后找到的子串T的位置
if(i) //串S中存在串T
{
StrDelete(S,i,StrLength(V));
k = StrInsert(S,i,V); //在原串T的位置插入串V
if(!K) //不能完全插入
{
exit(0);
}
i += StrLength(V); //注意
}
}while(i);
}int main()
{
SString T,S,F,Sub; //SString 本身已是一种指针类型
char *ch ,a[MAXSIZE + 1] = "abcdefgh"; //注意指针赋值的方式
ch = a;StrAssign(T,ch);
StrCopy(S,T);
StrPrint(T);
StrPrint(S);printf("%d\n",StrLength(T));
printf("%d\n",StrCompare(T,S));Concat(F,T,S);
StrPrint(F);SubString(Sub, T, 2,6 );
StrPrint(Sub);printf("%d\n",Index( F, Sub, 3));
StrInsert(F, 2 , Sub);
StrPrint(F);return 0 ;
}
第四章(1)定长顺序存储表示
最新推荐文章于 2024-03-18 09:07:15 发布