//算法4.1
int Index(String S.String T,int pos){
//T为非空穿;若主串S中第pos个字符之后存在与T相等的字串,
//则返回第一个这样的字串在S中的位置,否则返回0
if(pos>0){
n=StrLength(S);
m=StrLength(T);
i=pos;
while(i<=n-m+1){
SubString(sub,S,i,m);
if(StrCompare(sub,T)!=0)
i++;
else
return i; //返回字串在主串中的位置
}
}
return 0;
}
//算法4.2
status Concat(SString &T,SString S1,SString S2){
//用T返回由S1和S2联接而成的新串。若未截断,则返回TRUE,否则FALSE [0]存储该字符串的长度
if(S1[0]+S2[0]<=MAXSTRLEN){
//未截断
T[1..S1[0]]=S1[1..S1[0]];
T[S1[0]+1..S1[0]+S2[0]]=S2[1..S2[0]];
T[0]=S1[0]+S2[0];
uncut=true;
}
else if(S1[0]<MAXSTRLEN){
//截断
T[1..S1[0]]=S1[1..S1[0]];
T[S1[0]+1..MAXSTRLEN]=S2[1..MAXSTRLEN-S1[0]];
T[0]=MAXSTRLEN;
uncut=false;
}
else{
//截断仅取S1
T[0..MAXSTRLEN=S1[0..MAXSTRLEN];
uncut=false;
}
return uncut;
}
status SubString(SString &Sub,SString S,int pos,int len){
//用Sub返回串S的第pos个字符起长度为Len的字串
//其中,1<=pos<=StrLength(S)且0<=len<=StrLength(S)-pos+1
if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1)
return error;
Sub[1..len]=S[pos..pos+len-1];
Sub[0]=len;
return ok;
}
//------------串的堆分配存储表示---------------
typedef struct {
char *ch; //若是非空串,则按串长度分配存储区,否则ch为NULL
int length;
}HString;
//算法4.4
status StrInsert(HString &S,int pos,HString T){
//1<=pos<=StrLength(S)+1;在串S的第pos个字符之后插入串T
if(pos<1||pos>S.length+1)
return error;
if(T.length){
//T非空,则重新分配空间,插入T
if(!(S.ch=(char *)realloc(S.ch,(S.length+T.length)*sizeof(char))))
exit(OVERFLOW);
for(i=S.leng-1;i>=pos-1;i--) //为插入T而腾出位置
S.ch[i+T.length]=S.ch[i];
S.ch[pos-1..pos+T.leng-2]=T.ch[0..T.length-1]; //插入T
S.length+=T.length;
}
return ok;
}
//------------串的堆分配存储表示---------------
typedef struct {
char *ch; //若是非空串,则按串长度分配存储区,否则ch为NULL
int length;
}HString;
//------------基本操作的算法描述----------------
status StrAssign(HString &T,char *chars){
//生成一个其值等于串常量chars的串T
if(T.ch)
free(T.ch); //释放T原有空间
for(i=0,c=charc;c;i++,c++); //求chars的长度i
if(!i){
T.ch=NULL;
T.length=0;
}
else{
if(!(T.ch=(char *)malloc(i*sizeof(char))))
exit(OVERFLOW);
T.ch[0..i-1]=chars[0..i-1];
T.length=i;
}
return ok;
}
int StrLength(HString S){
//返回S中的元素个数,称为串的长度
return S.length;
}
int StrCompare(HString S,HString T){
//若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0;
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);
}
status ClearString(HString &S){
//将S清为空串
if(S.ch){
free(S.ch);
S.ch=NULL;
}
S.length=0;
return ok;
}
status Concat(HString &T,HString S1,HString S2){
//用T返回由S1和S2联接而成的新串
if(T.ch)
free(T.ch); //释放旧空间
if(!(T.ch=(char *)malloc((S1.length+S2.length)*sizeof(char))))
exit(OVERFLOW);
T.ch[0..S1.length-1]=S1.ch[0..S1.length-1];
T.length=S1.length+S2.length;
T.ch[S1.length..T.length-1]=S2.ch[0..S2.length-1];
return ok;
}
status SubString[HString &Sub,HString S,int pos,int len){
//用Sub返回串S的第pos个字符起长度为len的字串
//其中,1<=pos<=S.length且0<=len<=S.length-pos+1
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));
Sub.ch[0..len-1]=S.ch[pos-1..pos+len-2];
Sub.length=len;
}
return ok;
}
//--------------串的块链存储表示-----块链结构----------
#define CHUNKSIZE 80 //用户定义的块大小
typedef struct {
char ch[CHUNKSIZE];
struct Chunk *next;
}Chunk;
typedef struct {
Chunk *head,*tail; //串的头和尾指针
int curlen; //串的当前长度
}LString;
//算法4.5
int index(SString S,SString T,int pos){
//返回字串T在主串S中第pos个字符之后的位置、若不存在,则函数值为0;
//其中,T非空,1<=pos<=StrLength(S)
i=pos;
j=1;
while(i<=S[0]&&j<=T[0]){
if(S[i]==T[j])
{i++; j++;} //继续比较后继字符
else
{i=i-j+2; j=1;} //指针后退重新开始匹配
}
if(j>T[0])
return i-T[0];
else
return 0;
}
//算法4.6
int Index_KMP(SString S,SString T,int pos){
//利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法。
//其中,T非空,1<=pos<=StrLength(S)
i=pos;
j=1;
while(i<=S[0]&&j<=T[0]){
if(j==0||S[i]==T[j]){
i++;
j++;
}
else
j=next[j];
}
if(j>T[0])
return i-T[0];
else
return 0;
}
//算法4.7
void get_next(SString T,int next[]){
//求模式串T的next函数值并存入数组next
i=1;
next[1]=0;
j=0;
while(i<T[0]){
if(j==0||T[i]==T[j]){
i++;
j++;
next[i]=j;
}
else
j=next[j];
}
}
//算法4.8
void get_nextval(SString T,int nextval[]){
//求模式串T的next函数修正值并存入数组nextval
i=1;
nextval[1]=0;
j=0;
while(i<T[0]){
if(j==0||T[i]==T[j]){
i++;
j++;
if(T[i]!=T[j])
nextval[i]=j;
else
nextval[i]=nextval[j];
}
else
j=nextval[j];
}
}
//*******************************穿操作应用举例*********************
#define MaxBookNum 1000 //假设只对1000本书建索引表
#define MaxKeyNum 2500 //索引表的最大容量
#define MaxLineLen 500 //书目串的最大长度
#define MaxWordNum 10 //词表的最大容量
typedef struct{
char *item[]; //字符串的数组
int last; //词表的长度
}WordListType; //词表类型(顺序表)
typedef int ElemType; //定义链表的数据元素类型为整型(书号类型)
typedef struct{
HString key; //关键词
LinkList bnolist; //存放书号索引的链表
}IdxTermType; //索引项类型
typedef struct{
IdxTermType item[MaxKeyNum+1];
int last;
}IdxListType; //索引表类型(有序表)
//主要变量
char *buf; //书目串缓冲区
WordListType wdlist //词表
//算法4.9
void main(){
if(f=fopen("BookInfo.txt","r"))
if(g=fopen("BookIdx.txt","w")){
InitIdxList(idxlist); //初始化索引表idxlist为空表
while(!feof(f)){
GetLine(f); //从文件f读入一个书目信息到buf
ExtracKeyWord(BookNo); //从buf提取关键词到词表,书号存入BookIn
InsIdxList(idxlist,BookNo); //将书号为BookNo的关键词插入索引表
}
PutText(g,idxlist); //将生成的索引表idxlist输出到文件g
}
}
//算法4.10
status InsIdxList(IdxListType &idxlist,int bno){
for(i=0;i<wdlist.lst;i++){
GetWord(i,wd);
j=Locate(idxlist,wd,b);
if(!b)
InsertNewKey(idxlist,j,wd); //插入新的索引项
if(!InsertBook(idxlist,j,bno)) //插入书号索引
return OVERFLOW;
}
return ok;
}
//算法4.11
void GetWord(int i,HString &wd){
p=*(wdlist.item+1); //取词表中第i个字符串
StrAssign(wd,p); //生成关键字字符串
}
//算法4.12
int Locate(IdxListType &idxlist,HString wd,Boolean &b){
for(i=idxlist.last-1;(m=StrCompare(idxlist.item[i].key,wd))>0;i--);
if(m==0)
{b=TRUE; return i;} //找到
else
{b=FALSE; return i+1;}
}
//算法4.13
void InsertNewKey(int i,StrType wd){
for(j=idxlist.last-1;j>=i;j--) //后移索引项
idxlist.item[j+1]=idxlist.item[j];
//插入新的索引项
strCopy(idxlist.item[i].key,wd); //串赋值
InitList(idxlist.item[i].bonlist); //初始化书号索引表为空表
idxlist.last++;
}
//算法4.14
status InsertBook(IdxListType &idxlist,int i,int bno){
if(!MakeNode(p,bno)) //分配失败
return error;
Appand(idxlist.item[i].bnolist,p); //插入新的书号索引
return ok;
}
数据结构伪C代码:4.串
最新推荐文章于 2019-10-27 13:37:54 发布