anyview 数据结构习题集 第4章答案

4.10③ 编写对串求逆的递推算法。

要求实现以下函数:

void Reverse(StringType &s);

/* Reverse s by iteration. */

StringType是串的一个抽象数据类型,它包含以下6种基本操作:

void InitStr(StringType &s);

// 初始化s为空串。

void StrAssign(StringType &t, StringType s);

// s的值赋给ts的实际参数是串变量。

int StrCompare(StringType s, StringType t);

// 比较st。若s>t,返回值>0;若s=t,返回值=0;若s<t,返回值<0

 int StrLength(StringType s);

// 返回s中的元素个数,即该串的长度。

StringType Concat(StringType &s, StringType t);

// 返回由st联接而成的新串。

StringType SubString(StringType s, int start, int len);

// 1<=start<=StrLength(s)0<=len<=StrLength(s)- start+1时,

// 返回s中第start个字符起长度为len的子串,否则返回空串。

// 注意,不要使用 ” s = ” 的形式为 StringType 类型的变量赋值 ,

// 而要使用 StrAssign 函数!!!

void Reverse(StringType &s)

/* Reverse s by iteration. */

{

    StringType temp;

    int i=StrLength(s);

    InitStr(temp); //初始化空串

    //经测试,StrAssign(temp,'')错误~~原因未知

    while(i){

        Concat(temp,SubString(s,i,1));

       --i; //经测试,while(i--)就回出错~

    }

    StrAssign(s,temp);

}

 

4.12③ 编写一个实现串的置换操作Replace(&S,T,V)的算法。

要求实现以下函数:

void Replace(StringType &S, StringType T, StringType V);

/* 以串 置换串 中出现的所有和串 相同的非空串 */

StringType是串的一个抽象数据类型,它包含以下6种基本操作:

void InitStr(StringType &s);

// 初始化s为空串。

void StrAssign(StringType &t, StringType s);

// s的值赋给ts的实际参数是串变量。

int StrCompare(StringType s, StringType t);

// 比较st。若s>t,返回值>0;若s=t,返回值=0;若s<t,返回值<0

 int StrLength(StringType s);

// 返回s中的元素个数,即该串的长度。

StringType Concat(StringType &s, StringType t);

// 返回由st联接而成的新串。

StringType SubString(StringType s, int start, int len);

// 1<=start<=StrLength(s)0<=len<=StrLength(s)- start+1时,

// 返回s中第start个字符起长度为len的子串,否则返回空串。

// 注意,不要使用 ” s = ” 的形式为 StringType 类型的变量赋值 ,

// 而要使用 StrAssign 函数!!!

 

 

void Replace(StringType &S, StringType T, StringType V)

/* 以串 v 置换串 s 中出现的所有和串 t 相同的非空串  */

{

    int i=1,S_Len,T_Len,V_Len;

    StringType r;

    S_Len=StrLength(S);

    T_Len=StrLength(T);

    V_Len=StrLength(V);

    InitStr(r);

    while(i<=S_Len-T_Len+1){

        StrAssign(r,SubString(S,i,T_Len));

        if(0==StrCompare(r,T)){

            InitStr(r);

            Concat(r,SubString(S,1,i-1));

            Concat(r,V);

            Concat(r,SubString(S,i+T_Len,S_Len-T_Len-i+1));

            StrAssign(S,r);

            i+=V_Len;

            S_Len=StrLength(S);//注意要更新S的长度!

        }

        else{

            ++i;

        }

    }

}

 

4.13③ 编写算法,从串s中删除所有和串t相同的子串。

要求实现以下函数:

void DelSubString(StringType &scrStr, StringType subStr);

/* Remove all substring matching ‘subStr’ from ‘scrStr’. */

StringType是串的一个抽象数据类型,它包含以下6种基本操作:

void InitStr(StringType &s);

// 初始化s为空串。

void StrAssign(StringType &t, StringType s);

// s的值赋给ts的实际参数是串变量。

int StrCompare(StringType s, StringType t);

// 比较st。若s>t,返回值>0;若s=t,返回值=0;若s<t,返回值<0

 int StrLength(StringType s);

// 返回s中的元素个数,即该串的长度。

StringType Concat(StringType &s, StringType t);

// 返回由st联接而成的新串。

StringType SubString(StringType s, int start, int len);

// 1<=start<=StrLength(s)0<=len<=StrLength(s)- start+1时,

// 返回s中第start个字符起长度为len的子串,否则返回空串。

// 注意,不要使用 ” s = ” 的形式为 StringType 类型的变量赋值 ,

// 而要使用 StrAssign 函数!!!

 

 

void DelSubString(StringType &scrStr, StringType subStr)

/* Remove all substring matching 'subStr' from 'scrStr'. */

{

    int S_Len,T_Len,i=1;

    StringType temp;

    InitStr(temp);

    S_Len=StrLength(scrStr);

    T_Len=StrLength(subStr);

    while(i<=S_Len-T_Len+1){

        StrAssign(temp,SubString(scrStr,i,T_Len));

        if(0==StrCompare(temp,subStr)){

            InitStr(temp);

            Concat(temp,SubString(scrStr,1,i-1));

            Concat(temp,SubString(scrStr,T_Len+i,S_Len-T_Len-i+1));

            StrAssign(scrStr,temp);

            S_Len=StrLength(scrStr);

        }

        else{

            ++i; //注意这里删除substr后i不变!!

        }

    }

}

 

4.17③ 编写算法,实现串的基本操作Replace(&S,T,V)

要求采用教科书4.2.1节中所定义的定长顺序存储表示,

但不允许调用串的基本操作。

要求实现以下函数:

Status Replace(SString& s, SString t, SString v);

/* 用串v替换串s中所有和串t匹配的子串。 */

/* 若有与t匹配的子串被替换,则返回TRUE*/

/* 否则返回FALSE */

定长顺序串SString的类型定义:

typedef unsigned char SString[MAXSTRLEN+1];

/* s[0] is the string’s length */

 

 

Status Replace(SString& s, SString t, SString v)

/* 用串v替换串s中所有和串t匹配的子串。  */

/* 若有与t匹配的子串被替换,则返回TRUE;*/

/* 否则返回FALSE                        */

/*这道题要注意的是顺序串元素的移动*/

{

    //没通过,强烈怀疑测试数据有问题!!!

    int flag=0,i,j,k,pos,step;

    step=t[0]-v[0];//得到两个串的长度差

    for(i=1;i<=s[0]-t[0]+1;++i){//依次匹配串

        for(pos=i,j=1;j<=t[0];++pos,++j){

            if(s[pos]!=t[j]){//此处若写成 pos++和j++,那么下面t[0]<j+1

                break;

            } //如果不匹配,则退出循环

        }

        if(t[0]<j){//如果匹配成功

            if(0==step){//判断是否需要串元素

               for(j=1,k=i;j<=v[0];++k,++j){

                    s[k]=v[j];

                }

            }

            else if(step<0){//串t长度小于模式串的情况

                for(k=s[0];k>=i;--k){

                    s[k-step]=s[k];

                }

                for(j=1,k=i;j<=v[0];++k,++j){

                    s[k]=v[j];

                }

            }

             else {//t的长度大于模式串的情况

                for(k=pos;k<=s[0];++k){ //此处因为抄了前面的代码,所以没有注意到细节,导致

 

结果错误,已改正

                    s[k-step]=s[k];

                }

                for(j=1,k=i;j<=v[0];++k,++j){

                    s[k]=v[j];

                }

            }

            flag=1;//记录成功置换

            i+=v[0]-1;//i向后移动

            s[0]+=-step;//step为正时s[0]减小,step为负时,s[0]增加,故

        }

    }

    if(flag){

        return TRUE;

    }

    return FALSE;

}

 

4.20③ 编写算法,从串s中删除所有和串t相同的子串。

要求实现以下函数:

Status DelSub(SString &s, SString t);

/* 从串s中删除所有和串t匹配的子串。 */

/* 若有与t匹配的子串被删除,则返回TRUE*/

/* 否则返回FALSE */

定长顺序串SString的类型定义:

typedef unsigned char SString[MAXSTRLEN+1];

/* s[0] is the string’s length */

 

 

Status DelSub(SString &s, SString t)

/* 从串s中删除所有和串t匹配的子串。     */

/* 若有与t匹配的子串被删除,则返回TRUE;*/

/* 否则返回FALSE                        */

{

    int i,j,pos,flag=0;

    for(i=1;i<=s[0]-t[0]+1;++i){

        for(j=1,pos=i;j<=t[0];++j,++pos){ //模式串匹配

            if(s[pos]!=t[j]){

                break;

            }

        }

        if(j>t[0]){//删除操作--移动串元素

            for(;pos<=s[0];++pos){

                s[pos-t[0]]=s[pos];

            }

            s[0]-=t[0];

            flag=1; //标记成功删除

            --i; //关键点!!容易出错的地方,删除了元素之后,

                  //i保持不变,因循环会加1,故

        }

    }

    if(flag){

        return TRUE;

    }

    else{

        return FALSE;

    }

}

 

4.24③ 采用教科书4.2.2节中所定义的堆分配存储

表示。试写一算法,在串的堆存储结构上实现串基

本操作Concat(&T, s1, s2)

要求实现以下函数:

Status Concat(HString &S, HString S1, HString S2)

/* S返回由S1S2联接而成的新串 */

堆串HString的类型定义:

typedef struct {

char *ch; // 若是非空串,则按串长分配存储区,否则chNULL

int length; // 串长度

} HString;

//通过了忘记保存....

//并不难,不解释

 

4.30⑤ 假设以定长顺序存储结构表示串,试设计

一个算法,求串s中出现的第一个最长重复子串及

其位置,并分析你的算法的时间复杂度。

要求实现以下函数:

void CommonStr(SString s, SString &sub, int &loc);

/* 求串s中出现的第一个最长重复子串sub及其位置loc */

定长顺序串SString的类型定义:

typedef unsigned char SString[MAXSTRLEN+1];

/* s[0] is the string’s length */

//目前对此题没有好的解法,占位

 

 

posted @ 2011-05-15 10:55  hlb430  阅读(4217)  评论(1编辑  收藏  举报