4.10③ 編寫對串求逆的遞推算法。
要求實現以下函數:
void Reverse(StringType &s);
/* Reverse s by iteration. */
StringType是串的一個抽象數據類型,它包含以下6種基本操作:
void InitStr(StringType &s);
// 初始化s為空串。
void StrAssign(StringType &t, StringType s);
// 將s的值賦給t。s的實際參數是串變量。
int StrCompare(StringType s, StringType t);
// 比較s和t。若s>t,返回值>0;若s=t,返回值=0;若s<t,返回值<0。
int StrLength(StringType s);
// 返回s中的元素個數,即該串的長度。
StringType Concat(StringType &s, StringType t);
// 返回由s和t聯接而成的新串。
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);
/* 以串 v 置換串 s 中出現的所有和串 t 相同的非空串 */
StringType是串的一個抽象數據類型,它包含以下6種基本操作:
void InitStr(StringType &s);
// 初始化s為空串。
void StrAssign(StringType &t, StringType s);
// 將s的值賦給t。s的實際參數是串變量。
int StrCompare(StringType s, StringType t);
// 比較s和t。若s>t,返回值>0;若s=t,返回值=0;若s<t,返回值<0。
int StrLength(StringType s);
// 返回s中的元素個數,即該串的長度。
StringType Concat(StringType &s, StringType t);
// 返回由s和t聯接而成的新串。
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的值賦給t。s的實際參數是串變量。
int StrCompare(StringType s, StringType t);
// 比較s和t。若s>t,返回值>0;若s=t,返回值=0;若s<t,返回值<0。
int StrLength(StringType s);
// 返回s中的元素個數,即該串的長度。
StringType Concat(StringType &s, StringType t);
// 返回由s和t聯接而成的新串。
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返回由S1和S2聯接而成的新串 */
堆串HString的類型定義:
typedef struct {
char *ch; // 若是非空串,則按串長分配存儲區,否則ch為NULL
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 */
//目前對此題沒有好的解法,占位