第四章(2)串的堆分配的所有操作
利用堆来存储顺序表:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//--------ADT String 的表示与实现-------
//1、初始化字符串
//Status InitString(HString *T)
//2、生成一个其值等于串常量 chars 的串 T
//Status StrAssign(HString &T, char *chars);
//3、返回 S 的元素个数,成为串的长度
//int StrLength(HString S);
//4、若 S>T ,则返回值 >0 ,若S=T,则返回值 =0,若 S<T ,则返回值 <0.
//int StrCompare(HString S,HString T);
//5、将 S 清空为空串,并释放 S 所占空间
//Status ClearString(HString &S);
//6、用 T 返回由 S1 和 S2 链接而成的新串
//Status Concat(HString &T , HString S1, HString S2 );
//7、1<=pos<=StrLength(S) 且 0<=len<=StrLength(S)-pos + 1,返回串 S 的第pos 个字符起长度为 len 的子串
//HString SubString(HString S,int pos,int len);
//8、打印字符串
//Status StrPrint(HString T)
//9、字符串判空
//Status StrEmpty(HString T)
//10、删除字符串中某个位置固定长度的子串,pos是字符串中的位置,删除包括pos的len长
//Status StrDelete(HString *T, int pos, int len)
//11、pos是字符串中的位置,插入时原来的元素(包括pos位)后移
//Status StrInsert(HString *S, int pos, HString T);
//12、在字符串S中索引位置pos之后的子串t
//Status Index(HString S, HString T, int pos);
//13、将字符串T中等于S1的子串替换成为S2
//Status Replace(HString *T, HString S1, HString S2)//宏定义
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define STR_INIT_SIZE 100
#define STRINCREMENT 10
typedef int Status;
//-----串的堆分配存储表示-------
typedef struct{
char *ch; //若是非空串,则按串长分配存储区,否则 ch 为 NULL
int length; //串长度
}HString;
//------基本操作的算法描述-------
//1、初始化字符串
Status InitString(HString *T){
T->ch=NULL; //指针指向NULL,长度为0即可
T->length=0; //p.s.申请内存空间的过程在赋值中完成
return OK;
}
//2、生成一个其值等于串常量 chars 的串 T
Status StrAssign(HString *T, char *chars){
int i,len=strlen(chars);
char *c;
if(T->ch) free(T->ch); //释放T原有空间
for(i=0,c=chars ; *c ; ++i,++c ); //求chars的长度i
if(!i){
T->ch=NULL;
T->length=0;
return ERROR;
}
/* 也可以这样利用前面计算出来的 len 来计算
if (!len)
{
T->ch = NULL;
T->length = 0;
return ERROR;
} */
else{
T->ch=(char *)malloc(i * sizeof(char));
if(!T->ch)
exit(OVERFLOW);
for(i=0;i<len;++i){
T->ch[i]=chars[i]; // printf("%c",T.ch[i]);
}
T->length=len;
}
return OK;
}
//3、返回 S 的元素个数,成为串的长度
int StrLength(HString S){
return S.length;
}
//4、若 S>T ,则返回值 >0 ,若S=T,则返回值 =0,若 S<T ,则返回值 <0.
int StrCompare(HString S,HString T){
int i;
for(i=0;i<S.length && i<T.length ;i++)
if(S.ch[i]!=T.ch[i])
return (S.ch[i]-T.ch[i]);
return (S.length-T.length);
}
//5、将 S 清空为空串,并释放 S 所占空间
Status ClearString(HString &S){
if(S.ch)
{
free(S.ch);
S.ch=NULL;
}
S.length=0;
return OK;
}
//6、用 T 返回由 S1 和 S2 链接而成的新串
Status Concat(HString &T , HString S1, HString S2 ){
int i;
if(T.ch) free(T.ch); //释放旧的空间
if(!(T.ch=(char *)malloc((S1.length+S2.length)*sizeof(char))))
exit(OVERFLOW);
for(i=0;i<S1.length;i++)
T.ch[i]=S1.ch[i];
for(i=0;i<S2.length;i++)
T.ch[S1.length+i]=S2.ch[i];
T.length=S1.length+S2.length;
return OK;
}
//7、1<=pos<=StrLength(S) 且 0<=len<=StrLength(S)-pos + 1,返回串 S 的第pos 个字符起长度为 len 的子串
Status SubString(HString &Sub,HString S,int pos,int len){
int i;
if(pos<1 || pos>S.length || len<0 || len>S.length-pos+1)
return ERROR;
if(Sub.ch) free(Sub.ch); //释放旧空间
if(!len) { Sub.ch=NULL; Sub.length=0; } //孔子串的时候
else{
Sub.ch=(char *)malloc(len * sizeof(char));
for(i=0;i<len;i++)
Sub.ch[i]=S.ch[pos+i-1];
Sub.length=len;
}
return OK;
}
//8、打印字符串 ,通过长度判断打印的字符数
void StrPrint(HString T){
int i;
for(i=0;i<T.length;i++)
printf("%c",T.ch[i]);
printf("\n");
// return OK;
}
//9、字符串判空
Status StrEmpty(HString T){
if(T.length==0)
return TRUE;
else
return FALSE;
}
//10、删除字符串中某个位置固定长度的子串,pos是字符串中的位置,删除包括pos的len长
Status StrDelete(HString *T, int pos, int len){
int i;
if(pos>T->length)
return ERROR;
else if(pos+len>T->length)
len=T->length-pos+1;
for(i=pos-1;i<T->length+len;i++)
T->ch[i]=T->ch[i+len];
T->length-=len;
T->ch=(char *)realloc(T->ch,T->length*sizeof(char));
if(!T->ch)
exit(OVERFLOW);
return OK;
}
//11、pos是字符串中的位置,插入时原来的元素(包括pos位)后移
Status StrInsert(HString *S, int pos, HString T){
int i,len;
--pos;
len=StrLength(T);
S->ch= (char *)realloc(S->ch,(S->length+len)*sizeof(char));
if(!S->ch) exit(OVERFLOW);
if(pos>S->length)
pos=S->length;
for(i=S->length-1;i>pos-1;i--) //将pos位之后的向后移
S->ch[i+len]=S->ch[i];
for(i=0;i<len;i++)
S->ch[i+pos]=T.ch[i];
S->length+=len;
return OK;
}
//12、在字符串S中索引位置pos之后的子串T
Status Index(HString S, HString T, int pos){
if(StrEmpty(T))
return ERROR;
int i=pos-1,j=0;
while(i < S.length && j<T.length){
if( S.ch[i]==T.ch[j] ){
i++; j++;
}//if
else{
i=i-j+1; //重新返回,然后下一个
j=0;
}
}
if(j>=T.length)
return i-j+1; //返回找到之后的起始位置
else
return 0;
}
//13、将字符串T中等于S1的子串替换成为S2
Status Replace(HString *T, HString S1, HString S2){
//循环索引子串S1在字符串T中的位置(每次的位置从上一次位置后开始查找)
//从查找到的位置-1开始替换
//p.s.初始状态下S1为非空串
int pos=0;
if(StrEmpty(S1))
return ERROR;
do{
pos=Index(*T,S1,pos);
if(pos){
StrDelete(T,pos,StrLength(S1));
StrInsert(T,pos,S2);
}//if
}while(pos);
return OK;
}
//---------主函数----------
void main(){
HString t,s1,s2;
char *p1="hello xxxa",*p2="hello xxxb";
char *p="hello world !";
printf("String *p is: %s\n",p);
InitString(&t); //初始化
//----------判断是否为空
printf("t is empty and not?");
if(StrEmpty(t)==1)
printf(" YES!\n");
else
printf(" NO!\n");
StrAssign(&t,p);
printf("String t is: ");
//----------输出其 t 被赋值的数。
StrPrint(t);
printf("\n");
//----------输出 t 的长度
printf("the t String Length is : %d \n",StrLength(t));
//----------比较两个字符串的大小
InitString(&s1); //初始化
InitString(&s2); //初始化
StrAssign(&s1,p1);
StrAssign(&s2,p2);
printf("end of the A compare B is: %d \n",StrCompare(s1,s2));
printf("\n");
//---------共同使用的
HString c1,c2,c3;
char *b3="abcdefg",*b1="efg",*b2="hello";
InitString(&c1); //初始化
InitString(&c2); //初始化
InitString(&c3); //初始化
StrAssign(&c1,b1);
StrAssign(&c2,b2);
StrAssign(&c3,b3);
//----------index 的使用
//在字符串S中索引位置pos之后的子串T
printf("c1在c3的位置是: %d \n",Index(c3,c1,0));
//----------Replace 的使用
//将字符串T中等于S1的子串替换成为S2
printf("替换之前: ");
StrPrint(c3);
Replace(&c3,c1,c2);
printf("替换之后: ");
StrPrint(c3);
printf("\n");
//----------连接两个字符串
HString T;
InitString(&T); //初始化
Concat(T , s1, s2 );
StrPrint(T);
//删除包括pos的len长
printf("After String Delete: \n");
StrDelete(&T, 2, 3);
StrPrint(T);
printf("\n");
//----------返回串 S 的第pos 个字符起长度为 len 的子串
HString Sub;
InitString(&Sub); //初始化
SubString(Sub, T,4,5);
StrPrint(Sub);
//---------在pos 位上插入元素
printf("print the s1 and s2: ");
StrPrint(s2);
StrPrint(s2); printf("\n");
StrInsert(&s1, 4 , s2); //将 s2 插入到 s1 的第四个
printf("print the insert s1: ");
StrPrint(s1);
printf("\n");
//----------清空字符串
ClearString(Sub);
printf("Sub is empty and not?");
if(StrEmpty(Sub)==1)
printf(" YES!\n");
else
printf(" NO!\n");
}
--------------------------------------------------------------------------------------------------------------------------------如有补充,可以留言: