第四章(1)定长顺序存储表示

#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 ;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值