💡 【习题集】 ▼04 串
BIN
▼配套习题解析/▼04 串/_v_images/20181128012650395_14443.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
▼配套习题解析/▼04 串/_v_images/20181128012749064_24270.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
▼配套习题解析/▼04 串/_v_images/20181128012817985_10766.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
▼配套习题解析/▼04 串/_v_images/20181128013044407_30919.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
▼配套习题解析/▼04 串/_v_images/20181128013157410_30749.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
▼配套习题解析/▼04 串/_v_images/20181128013251526_202.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
▼配套习题解析/▼04 串/_v_images/20181128013312950_14120.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
36
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.10-main.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c"//**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
void Algo_4_10(SString T, SString S);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s = "0123456789";
|
||||
SString T, S;
|
||||
|
||||
printf("逆置前,T = ");
|
||||
StrAssign_Sq(T, s);
|
||||
StrPrint_Sq(T);
|
||||
printf("\n\n");
|
||||
|
||||
printf("逆置后,S = ");
|
||||
Algo_4_10(T, S);
|
||||
StrPrint_Sq(S);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.10:将T逆置为S┃
|
||||
┗━━━━━━━━━*/
|
||||
void Algo_4_10(SString T, SString S)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=T[0]; i>=1; i--)
|
||||
S[T[0]-i+1] = T[i];
|
||||
|
||||
S[0] = T[0];
|
||||
}
|
||||
67
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.11-main.c
Normal file
@@ -0,0 +1,67 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c"//**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
void Algo_4_11(SString R, SString S, SString T, int a[]);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int a[MAXSTRLEN+1];
|
||||
char *s = "amdhcjgfdlpinbefcopgkqikeb";
|
||||
char *t = "mhjlpinopkqik";
|
||||
SString T, S, R;
|
||||
int i;
|
||||
|
||||
printf("初始化S和T...\n");
|
||||
StrAssign_Sq(S, s);
|
||||
StrAssign_Sq(T, t);
|
||||
printf("\n");
|
||||
|
||||
printf("S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n");
|
||||
printf("T = ");
|
||||
StrPrint_Sq(T);
|
||||
printf("\n\n");
|
||||
|
||||
Algo_4_11(R, S, T, a);
|
||||
printf("R = ");
|
||||
StrPrint_Sq(R);
|
||||
printf("\n");
|
||||
printf("a = ");
|
||||
for(i=1; i<=a[0]; i++)
|
||||
printf("%d ", a[i]);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━┓
|
||||
┃题4.11:r=s-s∩t┃
|
||||
┗━━━━━━━━*/
|
||||
void Algo_4_11(SString R, SString S, SString T, int a[]) //数组a的0号存储a中元素个数
|
||||
{
|
||||
int i, p;
|
||||
SString Tmp;
|
||||
|
||||
StrAssign_Sq(R, "");
|
||||
Tmp[0] = 1;
|
||||
|
||||
for(i=1,a[0]=0; i<=S[0]; i++)
|
||||
{
|
||||
Tmp[1] = S[i]; //把S[i]变为串
|
||||
|
||||
p = Index_Sq_1(T, Tmp, 1); //判断S[i]是否在T中
|
||||
|
||||
if(!p)
|
||||
p = Index_Sq_1(R, Tmp, 1); //判断S[i]是否已出现过
|
||||
|
||||
if(!p)
|
||||
{
|
||||
a[0]++;
|
||||
a[a[0]] = i;
|
||||
StrInsert_Sq(R, a[0], Tmp);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
47
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.12-main.c
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c"//**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
Status Algo_4_12(SString S, SString T, SString V);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s = "----***--*-**-****-*****-----";
|
||||
char *t = "**";
|
||||
char *v = "^";
|
||||
SString T, S, V;
|
||||
|
||||
printf("替换前...\n");
|
||||
StrAssign_Sq(S, s);
|
||||
StrAssign_Sq(T, t);
|
||||
StrAssign_Sq(V, v);
|
||||
printf("S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n");
|
||||
printf("T = ");
|
||||
StrPrint_Sq(T);
|
||||
printf("\n");
|
||||
printf("V = ");
|
||||
StrPrint_Sq(V);
|
||||
printf("\n\n");
|
||||
|
||||
printf("替换后...\n");
|
||||
printf("S = ");
|
||||
Algo_4_12(S, T, V);
|
||||
StrPrint_Sq(S);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.12:字符串替换┃
|
||||
┗━━━━━━━━━*/
|
||||
Status Algo_4_12(SString S, SString T, SString V)
|
||||
{
|
||||
if(Replace_Sq(S, T, V)) //已定义
|
||||
return OK;
|
||||
else
|
||||
return ERROR;
|
||||
}
|
||||
41
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.13-main.c
Normal file
@@ -0,0 +1,41 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c"//**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
void Algo_4_13(SString S, SString T);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s = "----***--*-**-****-*****-----";
|
||||
char *t = "**";
|
||||
SString T, S;
|
||||
|
||||
printf("删除前...\n");
|
||||
StrAssign_Sq(S, s);
|
||||
StrAssign_Sq(T, t);
|
||||
printf("S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n");
|
||||
printf("T = ");
|
||||
StrPrint_Sq(T);
|
||||
printf("\n\n");
|
||||
|
||||
printf("删除后...\n");
|
||||
printf("S = ");
|
||||
Algo_4_13(S, T);
|
||||
StrPrint_Sq(S);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━━━┓
|
||||
┃题4.13:删除S中包含的T┃
|
||||
┗━━━━━━━━━━━*/
|
||||
void Algo_4_13(SString S, SString T)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=1; i=Index_Sq_1(S, T, 1); i++)
|
||||
StrDelete_Sq(S, i, T[0]);
|
||||
}
|
||||
137
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.14-main.c
Normal file
@@ -0,0 +1,137 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../../▲课本算法实现/▲02 线性表/01 SequenceList/SequenceList.c" //**▲02 线性表**//
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c" //**▲04 串**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define STACK_INIT_SIZE 100 //顺序栈存储空间的初始分配量
|
||||
#define STACKINCREMENT 10 //顺序栈存储空间的分配增量
|
||||
|
||||
/* 类型定义 */
|
||||
typedef SString SElemType; //栈元素类型为字符串数组
|
||||
typedef struct //栈结构类型
|
||||
{
|
||||
SElemType *base; //在栈构造之前和销毁之后,base的值为NULL
|
||||
SElemType *top; //栈顶指针
|
||||
int stacksize; //当前已分配的存储空间,以元素为单位
|
||||
}SqStack;
|
||||
|
||||
/* 函数原型 */
|
||||
Status InitStack_4_14(SqStack *S); //字符串栈的初始化
|
||||
Status Push_4_14(SqStack *S, SElemType e); //入栈
|
||||
Status Pop_4_14(SqStack *S, SElemType *e); //出栈
|
||||
Status Algo_4_14(SqList P, SString Str);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *p = "-+a*bc/de"; //后缀:abc*+de/-
|
||||
int i;
|
||||
SqList P;
|
||||
SString Str;
|
||||
|
||||
InitList_Sq(&P);
|
||||
for(i=1; i<=strlen(p); i++)
|
||||
ListInsert_Sq(&P, i, p[i-1]);
|
||||
printf("前缀表达式:P = ");
|
||||
for(i=0; i<P.length; i++)
|
||||
printf("%c", P.elem[i]);
|
||||
printf("\n\n");
|
||||
|
||||
Algo_4_14(P, Str);
|
||||
printf("后缀表达式:Str = ");
|
||||
StrPrint_Sq(Str);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━━━┓
|
||||
┃题4.14:前缀式变后缀式┃
|
||||
┗━━━━━━━━━━━*/
|
||||
/* 假设表达式变量均为单字符 */
|
||||
Status Algo_4_14(SqList P, SString Str)
|
||||
{
|
||||
int i;
|
||||
SElemType e1, e2, tmp;
|
||||
SqStack S;
|
||||
|
||||
InitStack_4_14(&S);
|
||||
|
||||
for(i=P.length-1; i>=0; i--) //从后往前读取
|
||||
{
|
||||
tmp[0] = 1;
|
||||
tmp[1] = P.elem[i];
|
||||
|
||||
if(isalpha(P.elem[i])) //遇到变量入栈
|
||||
Push_4_14(&S, tmp);
|
||||
else
|
||||
{
|
||||
Pop_4_14(&S, &e1); //遇到操作符连续出栈
|
||||
Pop_4_14(&S, &e2);
|
||||
|
||||
Concat_Sq(e1, e1, e2); //将出栈的两个变量与操作符正确连接
|
||||
Concat_Sq(e1, e1, tmp);
|
||||
|
||||
Push_4_14(&S, e1); //连接好的字符串入栈
|
||||
}
|
||||
}
|
||||
|
||||
Pop_4_14(&S, &tmp); //弹出转换完成后的字符串
|
||||
StrCopy_Sq(Str, tmp);
|
||||
|
||||
if(S.base==S.top) //最后栈应该为空
|
||||
return OK;
|
||||
else
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Status InitStack_4_14(SqStack *S)
|
||||
{
|
||||
(*S).base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
|
||||
if(!(*S).base)
|
||||
exit(OVERFLOW);
|
||||
|
||||
(*S).top = (*S).base;
|
||||
(*S).stacksize = STACK_INIT_SIZE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status Push_4_14(SqStack *S, SElemType e)
|
||||
{
|
||||
int i;
|
||||
|
||||
if((*S).top-(*S).base>=(*S).stacksize) //栈满,追加存储空间
|
||||
{
|
||||
(*S).base = (SElemType *)realloc((*S).base, ((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));
|
||||
if(!(*S).base)
|
||||
exit(OVERFLOW); //存储分配失败
|
||||
(*S).top = (*S).base + (*S).stacksize;
|
||||
(*S).stacksize += STACKINCREMENT;
|
||||
}
|
||||
|
||||
for(i=0; i<=e[0]; i++)
|
||||
(*(S->top))[i] = e[i]; //进栈先赋值,栈顶指针再自增
|
||||
|
||||
(S->top)++;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status Pop_4_14(SqStack *S, SElemType *e)
|
||||
{
|
||||
int i;
|
||||
|
||||
if((*S).top==(*S).base)
|
||||
return ERROR;
|
||||
|
||||
(*S).top--; //出栈栈顶指针先递减,再赋值
|
||||
|
||||
for(i=0; i<=(*((*S).top))[0]; i++)
|
||||
(*e)[i] = (*((*S).top))[i];
|
||||
|
||||
return OK;
|
||||
}
|
||||
156
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.15~4.17-main.c
Normal file
@@ -0,0 +1,156 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c" //**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
Status Algo_4_15(SString T, char *chars);
|
||||
int Algo_4_16(SString S, SString T);
|
||||
Status Algo_4_17(SString S, SString T, SString V);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *t = "ab**c*de***fg";
|
||||
char *s = "ab**c*de***fh";
|
||||
int i;
|
||||
SString T, S, M1, M2;
|
||||
|
||||
printf("███题 4.15 验证...███\n");
|
||||
Algo_4_15(T, t);
|
||||
Algo_4_15(S, s);
|
||||
printf("T = ");
|
||||
StrPrint_Sq(T);
|
||||
printf("\n");
|
||||
printf("S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n\n");
|
||||
|
||||
printf("███题 4.16 验证...███\n");
|
||||
i = Algo_4_16(S, T);
|
||||
if(i>0)
|
||||
printf("S > T\n");
|
||||
else if(i<0)
|
||||
printf("S < T\n");
|
||||
else
|
||||
printf("S == T\n");
|
||||
printf("\n");
|
||||
|
||||
printf("███题 4.17 验证...███\n");
|
||||
Algo_4_15(M1, "**");
|
||||
Algo_4_15(M2, "^");
|
||||
Algo_4_17(S, M1, M2);
|
||||
printf("用 \"^\" 替换 \"**\" 后:S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.15:字符串赋值┃
|
||||
┗━━━━━━━━━*/
|
||||
Status Algo_4_15(SString T, char *chars)
|
||||
{
|
||||
int i, len;
|
||||
|
||||
len = strlen(chars);
|
||||
|
||||
if(len>MAXSTRLEN) //chars过长
|
||||
return ERROR;
|
||||
else
|
||||
{
|
||||
T[0] = len;
|
||||
for(i=1; i<=len; i++)
|
||||
T[i] = chars[i-1]; //chars为常量
|
||||
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.16:字符串比较┃
|
||||
┗━━━━━━━━━*/
|
||||
int Algo_4_16(SString S, SString T)
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
while(i<=S[0] && i<=T[0])
|
||||
{
|
||||
if(S[i]==T[i])
|
||||
i++;
|
||||
else
|
||||
return S[i] - T[i];
|
||||
}
|
||||
|
||||
return S[0] - T[0];
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.17:字符串替换┃
|
||||
┗━━━━━━━━━*/
|
||||
Status Algo_4_17(SString S, SString T, SString V)
|
||||
{
|
||||
int count = 1; //count遍历S
|
||||
int i, j, k;
|
||||
SString Tmp_beh;
|
||||
|
||||
i = count;
|
||||
j = 1;
|
||||
while(i>=1 && i<=S[0] && j<=T[0]) //寻找第一个匹配的位置
|
||||
{
|
||||
if(S[i]==T[j])
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = i - (j-1) +1; //j-1代表徒劳地前进了j-1个位置
|
||||
j = 1;
|
||||
}
|
||||
}
|
||||
if(j>T[0] && T[0]!=0) //T不为空串
|
||||
count = i-T[0]; //匹配成功
|
||||
else
|
||||
count = 0;
|
||||
|
||||
while(S[0]-T[0]+V[0]<=MAXSTRLEN && count!=0) //有匹配的字符串且可以被完全替换
|
||||
{
|
||||
Tmp_beh[0] = S[0]-i+1; //摘取S中匹配字符串之后的字符到Tmp_beh
|
||||
for(k=1; k<=S[0]-i+1; k++)
|
||||
Tmp_beh[k] = S[k+i-1];
|
||||
|
||||
S[0] = S[0]-T[0]+V[0];
|
||||
for(k=1; k<=V[0]; k++) //联接V到S上
|
||||
S[k+count-1] = V[k];
|
||||
|
||||
for(k=count+V[0]; k<=S[0]; k++) //联接取自S中的后半部分到S上
|
||||
S[k] = Tmp_beh[k-count-V[0]+1];
|
||||
|
||||
count += V[0]; //i切换到下一个位置
|
||||
|
||||
i = count;
|
||||
j = 1;
|
||||
while(i>=1 && i<=S[0] && j<=T[0]) //定位下一个匹配的字符串
|
||||
{
|
||||
if(S[i]==T[j])
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = i - (j-1) +1; //j-1代表徒劳地前进了j-1个位置
|
||||
j = 1;
|
||||
}
|
||||
}
|
||||
if(j>T[0] && T[0]!=0) //T不为空串
|
||||
count = i-T[0]; //匹配成功
|
||||
else
|
||||
count = 0;
|
||||
}
|
||||
|
||||
if(count==0) //S中的T已全部被替换
|
||||
return OK;
|
||||
else //S中尚有T,但是V已经插不进去了
|
||||
return ERROR;
|
||||
}
|
||||
48
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.18-main .c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c" //**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
void Algo_4_18(SString S, int total[]);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s = "dbasydujhge638940[gptokljrsehgadcsbnmv,c.b'ng[p098437eywdghswqdecxvghju";
|
||||
SString S;
|
||||
int total[128] = {};
|
||||
int i;
|
||||
|
||||
StrAssign_Sq(S, s);
|
||||
printf("S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n\n");
|
||||
|
||||
Algo_4_18(S, total);
|
||||
printf(" S 中不同的字符共计 %d 个:\n", total[0]);
|
||||
for(i=1; i<=127; i++)
|
||||
{
|
||||
if(total[i]!=0)
|
||||
printf("字符 \'%c\' 有 %d 个.\n", i, total[i]);
|
||||
}
|
||||
printf("统计完毕...\n");
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃题4.18:统计字符串中不同字符总数和每种字符的个数┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
/* 利用字符与数字对应的特性 */
|
||||
void Algo_4_18(SString S, int total[]) //total长度设为128,代表各种不同字符
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=1; i<=S[0]; i++) //字符串中间无空字符
|
||||
{
|
||||
if(!total[S[i]]) //此处无字符
|
||||
total[0]++; //不同字符总数
|
||||
|
||||
total[S[i]]++; //各种字符个数
|
||||
}
|
||||
}
|
||||
83
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.19-main .c
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c"//**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
void Algo_4_19(SString R, SString S, SString T, int a[]);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int a[MAXSTRLEN+1];
|
||||
char *s = "amdhcjgfdlpinbefcopgkqikeb";
|
||||
char *t = "mhjlpinopkqik";
|
||||
SString T, S, R;
|
||||
int i;
|
||||
|
||||
printf("初始化S和T...\n");
|
||||
StrAssign_Sq(S, s);
|
||||
StrAssign_Sq(T, t);
|
||||
printf("\n");
|
||||
|
||||
printf("S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n");
|
||||
printf("T = ");
|
||||
StrPrint_Sq(T);
|
||||
printf("\n\n");
|
||||
|
||||
Algo_4_19(R, S, T, a);
|
||||
printf("R = ");
|
||||
StrPrint_Sq(R);
|
||||
printf("\n");
|
||||
printf("a = ");
|
||||
for(i=1; i<=a[0]; i++)
|
||||
printf("%d ", a[i]);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━┓
|
||||
┃题4.19:r=s-s∩t┃
|
||||
┗━━━━━━━━*/
|
||||
void Algo_4_19(SString R, SString S, SString T, int a[]) //数组a的0号存储a中元素个数
|
||||
{
|
||||
int i, j, k;
|
||||
int flag;
|
||||
|
||||
a[0] = 0;
|
||||
R[0] = 0; //初始化R
|
||||
|
||||
for(i=1; i<=S[0]; i++)
|
||||
{
|
||||
flag = 0;
|
||||
|
||||
for(j=1; j<=T[0]; j++)
|
||||
{
|
||||
if(S[i]==T[j])
|
||||
{
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flag) //S[i]中的元素不在T中
|
||||
{
|
||||
for(k=1; k<=R[0]; k++)
|
||||
{
|
||||
if(S[i]==R[k])
|
||||
{
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!flag) //S[i]不在R中
|
||||
{
|
||||
R[0]++;
|
||||
a[0]++;
|
||||
R[R[0]] = S[i];
|
||||
a[a[0]] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
85
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.20-main .c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c"//**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
void Algo_4_20(SString S, SString T);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s = "----***--*-**-****-*****-----";
|
||||
char *t = "**";
|
||||
SString T, S;
|
||||
|
||||
printf("删除前...\n");
|
||||
StrAssign_Sq(S, s);
|
||||
StrAssign_Sq(T, t);
|
||||
printf("S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n");
|
||||
printf("T = ");
|
||||
StrPrint_Sq(T);
|
||||
printf("\n\n");
|
||||
|
||||
printf("删除后...\n");
|
||||
printf("S = ");
|
||||
Algo_4_20(S, T);
|
||||
StrPrint_Sq(S);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━━━┓
|
||||
┃题4.20:删除S中包含的T┃
|
||||
┗━━━━━━━━━━━*/
|
||||
void Algo_4_20(SString S, SString T)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
i = 1;
|
||||
j = 1;
|
||||
while(i<=S[0] && j<=T[0]) //寻找第一个匹配的位置
|
||||
{
|
||||
if(S[i]==T[j])
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = i - (j-1) +1; //j-1代表徒劳地前进了j-1个位置
|
||||
j = 1;
|
||||
}
|
||||
}
|
||||
if(j>T[0] && T[0]) //T不为空串
|
||||
i = i-T[0]; //匹配成功
|
||||
else
|
||||
i = 0;
|
||||
|
||||
while(i!=0) //有匹配的字符串
|
||||
{
|
||||
for(k=i+T[0]; k<=S[0]; k++)
|
||||
S[k-T[0]] = S[k];
|
||||
S[0] = S[0] - T[0]; //改变S长度
|
||||
|
||||
j = 1;
|
||||
while(i<=S[0] && j<=T[0]) //定位下一个匹配的字符串
|
||||
{
|
||||
if(S[i]==T[j])
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = i - (j-1) +1; //j-1代表徒劳地前进了j-1个位置
|
||||
j = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(j>T[0] && T[0]!=0) //T不为空串
|
||||
i = i-T[0]; //匹配成功
|
||||
else
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
233
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.21-main .c
Normal file
@@ -0,0 +1,233 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../../▲课本算法实现/▲02 线性表/04 SinglyLinkedList/SinglyLinkedList.c" //**▲02 线性表**//
|
||||
|
||||
/* 类型定义 */
|
||||
typedef LElemType_L strElem;
|
||||
typedef LNode strNode;
|
||||
typedef LinkList String;
|
||||
|
||||
/* 函数原型 */
|
||||
Status StrAssign_4_21(String *S, char *chars);
|
||||
Status StrCopy_4_21(String *S, String T);
|
||||
int StrCompare_4_21(String S, String T);
|
||||
int StrLength_4_21(String S);
|
||||
Status Concat_4_21(String *R, String S, String T);
|
||||
Status SubString_4_21(String *Sub, String S, int pos, int len);
|
||||
void StrPrint_4_21(String S);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *chars = "@@***#*%%%****(((((*****)))";
|
||||
String S, T, R, Sub;
|
||||
int i;
|
||||
|
||||
StrAssign_4_21(&T, chars);
|
||||
printf("T = ");
|
||||
StrPrint_4_21(T);
|
||||
printf("\n\n");
|
||||
|
||||
StrCopy_4_21(&S, T);
|
||||
printf("S = ");
|
||||
StrPrint_4_21(S);
|
||||
printf("\n\n");
|
||||
|
||||
i = StrCompare_4_21(S, T);
|
||||
if(i>0)
|
||||
printf("S > T\n");
|
||||
else if (i<0)
|
||||
printf("S < T\n");
|
||||
else
|
||||
printf("S = T\n");
|
||||
printf("\n");
|
||||
|
||||
i = StrLength_4_21(S);
|
||||
printf("S_len = %d\n", i);
|
||||
printf("\n");
|
||||
|
||||
Concat_4_21(&R, S, T);
|
||||
printf("R = ");
|
||||
StrPrint_4_21(R);
|
||||
printf("\n\n");
|
||||
|
||||
SubString_4_21(&Sub, S, 11, 4);
|
||||
printf("Sub = ");
|
||||
StrPrint_4_21(Sub);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.21:字符串赋值┃
|
||||
┗━━━━━━━━━*/
|
||||
/* (1) */
|
||||
Status StrAssign_4_21(String *S, char *chars)
|
||||
{
|
||||
int i, len;
|
||||
String s, p;
|
||||
|
||||
len = strlen(chars);
|
||||
|
||||
InitList_L(S);
|
||||
|
||||
for(i=1,p=*S; i<=len; i++)
|
||||
{
|
||||
s = (String)malloc(sizeof(strNode));
|
||||
if(!s)
|
||||
exit(OVERFLOW);
|
||||
s->data = chars[i-1];
|
||||
|
||||
s->next = p->next;
|
||||
p->next = s;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.21:字符串复制┃
|
||||
┗━━━━━━━━━*/
|
||||
/* (2) */
|
||||
Status StrCopy_4_21(String *S, String T)
|
||||
{
|
||||
String r, p, s;
|
||||
|
||||
if(!T)
|
||||
return ERROR;
|
||||
|
||||
InitList_L(S);
|
||||
|
||||
for(r=*S,p=T->next; p; p=p->next)
|
||||
{
|
||||
s = (String)malloc(sizeof(strNode));
|
||||
if(!s)
|
||||
exit(OVERFLOW);
|
||||
s->data = p->data;
|
||||
|
||||
s->next = r->next;
|
||||
r->next = s;
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.21:字符串比较┃
|
||||
┗━━━━━━━━━*/
|
||||
/* (3) */
|
||||
int StrCompare_4_21(String S, String T)
|
||||
{
|
||||
String p, q;
|
||||
|
||||
if(S && T)
|
||||
{
|
||||
p = S->next;
|
||||
q = T->next;
|
||||
|
||||
while(p && q)
|
||||
{
|
||||
if(p->data!=q->data)
|
||||
return p->data - q->data;
|
||||
|
||||
p = p->next;
|
||||
q = q->next;
|
||||
}
|
||||
|
||||
return ListLength_L(S)-ListLength_L(T);
|
||||
}
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.21:字符串求长┃
|
||||
┗━━━━━━━━━*/
|
||||
/* (4) */
|
||||
int StrLength_4_21(String S)
|
||||
{
|
||||
return ListLength_L(S);
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.21:字符串拼接┃
|
||||
┗━━━━━━━━━*/
|
||||
/* (5) */
|
||||
Status Concat_4_21(String *R, String S, String T)
|
||||
{
|
||||
String r, p, s;
|
||||
|
||||
if(!S || !T)
|
||||
return ERROR;
|
||||
|
||||
InitList_L(R);
|
||||
|
||||
for(r=*R,p=S->next; p; p=p->next)
|
||||
{
|
||||
s = (String)malloc(sizeof(strNode));
|
||||
if(!s)
|
||||
exit(OVERFLOW);
|
||||
s->data = p->data;
|
||||
|
||||
s->next = r->next;
|
||||
r->next = s;
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
for(p=T->next; p; p=p->next)
|
||||
{
|
||||
s = (String)malloc(sizeof(strNode));
|
||||
if(!s)
|
||||
exit(OVERFLOW);
|
||||
s->data = p->data;
|
||||
|
||||
s->next = r->next;
|
||||
r->next = s;
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.21:字符串提取┃
|
||||
┗━━━━━━━━━*/
|
||||
/* (6) */
|
||||
Status SubString_4_21(String *Sub, String S, int pos, int len)
|
||||
{
|
||||
int i, sl;
|
||||
String r, p, s;
|
||||
|
||||
sl = StrLength_4_21(S);
|
||||
|
||||
if(!S || pos<1 || pos>sl || len<0 || pos+len-1>sl)
|
||||
return ERROR;
|
||||
|
||||
InitList_L(Sub);
|
||||
|
||||
for(i=1,p=S->next; i<pos; i++,p=p->next)
|
||||
; //寻找第pos个结点
|
||||
|
||||
for(i=1,r=*Sub; i<=len; i++,p=p->next)
|
||||
{
|
||||
s = (String)malloc(sizeof(strNode));
|
||||
if(!s)
|
||||
exit(OVERFLOW);
|
||||
s->data = p->data;
|
||||
|
||||
s->next = r->next;
|
||||
r->next = s;
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* 字符串输出 */
|
||||
void StrPrint_4_21(String S)
|
||||
{
|
||||
String p;
|
||||
|
||||
for(p=S->next; p; p=p->next)
|
||||
printf("%c", p->data);
|
||||
}
|
||||
50
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.22-main .c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲04 串/03 BlockChainString/BlockChainString.c"//**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
void Algo_4_22(LString S, LString *T, char ch);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *t = "----***--*-**-**^**-*****-----";
|
||||
char *s = "12345";
|
||||
char ch = '^';
|
||||
LString T, S;
|
||||
|
||||
StrAssign_L(&T, t);
|
||||
StrAssign_L(&S, s);
|
||||
printf("T = ");
|
||||
StrPrint_L(T);
|
||||
printf("\n");
|
||||
printf("S = ");
|
||||
StrPrint_L(S);
|
||||
printf("\n\n");
|
||||
|
||||
Algo_4_22(S, &T, ch);
|
||||
printf("T = ");
|
||||
StrPrint_L(T);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃题4.22:将S插入到T的某个字符之后,若不存在则插在T的末位 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
void Algo_4_22(LString S, LString *T, char ch)
|
||||
{
|
||||
int i;
|
||||
char tmp[2];
|
||||
LString Tmp;
|
||||
|
||||
tmp[0] = ch;
|
||||
tmp[1] = '\0';
|
||||
StrAssign_L(&Tmp, tmp);
|
||||
|
||||
i = Index_L((*T), Tmp, 1); //寻找字符ch在T中的位置
|
||||
|
||||
if(i)
|
||||
StrInsert_L(T, i+1, S); //S插入在T的第i+1个字符前
|
||||
else
|
||||
StrInsert_L(T, (*T).curlen+1, S); //S插入在T的最后
|
||||
}
|
||||
70
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.23-main .c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲03 栈和队列/01 SequenceStack/SequenceStack.c"//**▲03 栈和队列**//
|
||||
#include "../../../▲课本算法实现/▲04 串/03 BlockChainString/BlockChainString.c"//**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
Status Algo_4_23(LString T);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *t = "abcdefgfedcba";
|
||||
LString T;
|
||||
|
||||
StrAssign_L(&T, t);
|
||||
printf("T = ");
|
||||
StrPrint_L(T);
|
||||
printf("\n\n");
|
||||
|
||||
Algo_4_23(T) ? printf("T是对称串!") : printf("T是非对称串!!");
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━━━┓
|
||||
┃题4.23:判断串是否对称┃
|
||||
┗━━━━━━━━━━━*/
|
||||
/* 借助于栈的操作来实现此函数,栈中数据元素定义为char */
|
||||
Status Algo_4_23(LString T)
|
||||
{
|
||||
int i, j, m;
|
||||
SqStack S;
|
||||
SElemType_Sq e;
|
||||
Chunk *p;
|
||||
|
||||
if(!(T.curlen))
|
||||
return OK;
|
||||
|
||||
InitStack_Sq(&S);
|
||||
m = T.curlen/2;
|
||||
|
||||
for(i=1,p=T.head,j=0; i<=m; i++)
|
||||
{
|
||||
Push_Sq(&S, p->ch[j]);
|
||||
j = (j+1) % CHUNKSIZE;
|
||||
if(!j)
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if(T.curlen % 2) //长度为奇数则跳过一个字符
|
||||
{
|
||||
i++;
|
||||
j = (j+1) % CHUNKSIZE;
|
||||
if(!j)
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
while(!StackEmpty_Sq(S) && i<=T.curlen)
|
||||
{
|
||||
Pop_Sq(&S, &e);
|
||||
if(e!=p->ch[j])
|
||||
return ERROR;
|
||||
i++;
|
||||
j = (j+1) % CHUNKSIZE;
|
||||
if(!j)
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if(StackEmpty_Sq(S) && i>T.curlen)
|
||||
return OK;
|
||||
}
|
||||
91
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.24~4.26-main .c
Normal file
@@ -0,0 +1,91 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../../▲课本算法实现/▲04 串/02 HeapString/HeapString.c"//**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
Status Concat_4_24(HString *T, HString S1, HString S2);
|
||||
Status Replace_4_25(HString *S, HString T, HString V);
|
||||
Status StrInsert_4_26(HString *S, int pos, HString T);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s = "---*^***^*^*^*---";
|
||||
char *s1 = "*";
|
||||
char *s2 = "^*";
|
||||
char *v = "*_*";
|
||||
HString S1, S2, T, V, S;
|
||||
|
||||
StrAssign_H(&S1, s1);
|
||||
StrAssign_H(&S2, s2);
|
||||
StrAssign_H(&V, v);
|
||||
StrAssign_H(&S, s);
|
||||
|
||||
printf("S1 = ");
|
||||
StrPrint_H(S1);
|
||||
printf("\n");
|
||||
printf("S2 = ");
|
||||
StrPrint_H(S2);
|
||||
printf("\n");
|
||||
printf("V = ");
|
||||
StrPrint_H(V);
|
||||
printf("\n");
|
||||
printf("S = ");
|
||||
StrPrint_H(S);
|
||||
printf("\n\n");
|
||||
|
||||
printf("███题 4.24 验证...███\n");
|
||||
printf("连接S1和S2为T...\n");
|
||||
Concat_4_24(&T, S1, S2);
|
||||
printf("T = ");
|
||||
StrPrint_H(T);
|
||||
printf("\n\n");
|
||||
|
||||
printf("███题 4.25 验证...███\n");
|
||||
printf("用 V 替换 S 中的 T...\n");
|
||||
Replace_4_25(&S, T, V);
|
||||
printf("S = ");
|
||||
StrPrint_H(S);
|
||||
printf("\n\n");
|
||||
|
||||
printf("███题 4.26 验证...███\n");
|
||||
printf("将 T 插入到 S 的第 2 个字符前...\n");
|
||||
StrInsert_4_26(&S, 2, T);
|
||||
printf("S = ");
|
||||
StrPrint_H(S);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━┓
|
||||
┃题4.24:串连接┃
|
||||
┗━━━━━━━*/
|
||||
Status Concat_4_24(HString *T, HString S1, HString S2)
|
||||
{
|
||||
if(Concat_H(T, S1, S2)) //已定义
|
||||
return OK;
|
||||
else
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*━━━━━━━┓
|
||||
┃题4.25:串替换┃
|
||||
┗━━━━━━━*/
|
||||
Status Replace_4_25(HString *S, HString T, HString V)
|
||||
{
|
||||
if(Replace_H(S, T, V)) //已定义
|
||||
return OK;
|
||||
else
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*━━━━━━━┓
|
||||
┃题4.26:串插入┃
|
||||
┗━━━━━━━*/
|
||||
Status StrInsert_4_26(HString *S, int pos, HString T)
|
||||
{
|
||||
if(StrInsert_H(S, pos, T)) //已定义
|
||||
return OK;
|
||||
else
|
||||
return ERROR;
|
||||
}
|
||||
60
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.27-main .c
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c" //**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
int Algo_4_27(SString S, SString T, int pos);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s = "aaaaaaaaaaaaaaab";
|
||||
char *t = "aaaab";
|
||||
SString S, T;
|
||||
|
||||
StrAssign_Sq(S, s);
|
||||
StrAssign_Sq(T, t);
|
||||
printf("S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n");
|
||||
printf("T = ");
|
||||
StrPrint_Sq(T);
|
||||
printf("\n\n");
|
||||
|
||||
printf("T在S中首次出现的位置为:");
|
||||
printf("%d\n", Algo_4_27(S, T, 1));
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━┓
|
||||
┃题4.27:子串定位┃
|
||||
┗━━━━━━━━*/
|
||||
int Algo_4_27(SString S, SString T, int pos)
|
||||
{
|
||||
int i = pos;
|
||||
int j = 1;
|
||||
|
||||
if(pos<1)
|
||||
return 0;
|
||||
|
||||
while(i<=S[0] && j<=T[0])
|
||||
{
|
||||
|
||||
if((j!=1&&S[i]==T[j])||(j==1&&S[i]==T[j]&&S[i+T[0]-1]==T[T[0]]))
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = i - (j-1) +1;
|
||||
j = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(j>T[0] && T[0]) //T不为空串
|
||||
return i-T[0]; //匹配成功
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
204
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.28~4.29-main .c
Normal file
@@ -0,0 +1,204 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 串结构类型定义 */
|
||||
typedef struct strLNode //主串是个双向链表(不循环),模式串在未求next值之前与主串类似
|
||||
{
|
||||
char chdata;
|
||||
struct strLNode *succ; //succ指向后继
|
||||
struct strLNode *next; //next在主串中,指向前驱
|
||||
}strLNode; //next在模式串中,指向当前结点失配时,下一个应该比较的结点
|
||||
typedef strLNode *LString;
|
||||
|
||||
/* 函数原型 */
|
||||
Status Algo_4_28_1(LString T);
|
||||
Status Algo_4_28_2(LString T) ;
|
||||
int Algo_4_29(LString S, LString T, int pos);
|
||||
Status AssignLString(LString *S, char *s);
|
||||
Status PrintLString(LString S);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int pos, i1, i2;
|
||||
LString S, T1, T2;
|
||||
char *s = "abaaabaababaabcaabaabcacabaabcaabaabcac";
|
||||
char *t = "abaabcac";
|
||||
LString p;
|
||||
AssignLString(&S, s); //主串
|
||||
AssignLString(&T1, t); //模式串
|
||||
AssignLString(&T2, t);
|
||||
|
||||
printf("主 串 :S = ");
|
||||
PrintLString(S);
|
||||
printf("\n");
|
||||
printf("模式串 :T1 = ");
|
||||
PrintLString(T1);
|
||||
printf("\n");
|
||||
printf("模式串 :T2 = ");
|
||||
PrintLString(T2);
|
||||
printf("\n\n");
|
||||
|
||||
printf("███题 4.28 验证...███\n");
|
||||
Algo_4_28_1(T1);
|
||||
Algo_4_28_2(T2);
|
||||
printf("创建next表...\n");
|
||||
printf("\n");
|
||||
|
||||
printf("███题 4.29 验证...███\n");
|
||||
i1 = Algo_4_29(S, T1, 1);
|
||||
printf("模式串 T1 从 %d 个字符起第一次匹配成功的位置为i1 = %d\n", 1, i1);
|
||||
|
||||
i2 = Algo_4_29(S, T2, 1);
|
||||
printf("模式串 T2 从 %d 个字符起第一次匹配成功的位置为i2 = %d\n", 1, i2);
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.28-1:求next值┃
|
||||
┗━━━━━━━━━*/
|
||||
/* 方案1:求next值 */
|
||||
Status Algo_4_28_1(LString T)
|
||||
{
|
||||
strLNode *i, *j;
|
||||
|
||||
if(!T || !T->succ)
|
||||
return ERROR;
|
||||
|
||||
i = T->succ; //i = 1
|
||||
j = T; //j = 0
|
||||
|
||||
i->next = T; //第一个字符处失配
|
||||
|
||||
while(i->succ)
|
||||
{
|
||||
if(j==T || i->chdata==j->chdata)
|
||||
{
|
||||
i = i->succ;
|
||||
j = j->succ;
|
||||
i->next = j;
|
||||
}
|
||||
else
|
||||
j = j->next;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━┓
|
||||
┃题4.28-2:求next值┃
|
||||
┗━━━━━━━━━*/
|
||||
/* 方案2:求nextval值,即改进后的求next方案 */
|
||||
Status Algo_4_28_2(LString T)
|
||||
{
|
||||
strLNode *i, *j;
|
||||
|
||||
if(!T || !T->succ)
|
||||
return ERROR;
|
||||
|
||||
i = T->succ; //i = 1
|
||||
j = T; //j = 0
|
||||
|
||||
i->next = T; //第一个字符处失配
|
||||
|
||||
while(i->succ)
|
||||
{
|
||||
if(j==T || i->chdata==j->chdata)
|
||||
{
|
||||
i = i->succ;
|
||||
j = j->succ;
|
||||
|
||||
if(i->chdata!=j->chdata)
|
||||
i->next = j;
|
||||
else
|
||||
i->next = j->next;
|
||||
}
|
||||
else
|
||||
j = j->next;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*━━━━━━━━┓
|
||||
┃题4.29:KMP算法 ┃
|
||||
┗━━━━━━━━*/
|
||||
int Algo_4_29(LString S, LString T, int pos)
|
||||
{
|
||||
int count, m;
|
||||
strLNode *i, *j; //i遍历S,j遍历T
|
||||
strLNode *p, *q;
|
||||
|
||||
if(pos<1 || !S || !S->succ || !T || !T->succ)
|
||||
return 0;
|
||||
|
||||
for(count=1,i=S->succ; count<pos; count++,i=i->succ)
|
||||
; //用i指向第pos个结点
|
||||
|
||||
j = T->succ;
|
||||
p = i;
|
||||
|
||||
while(i && j)
|
||||
{
|
||||
if(j==T || i->chdata==j->chdata)
|
||||
{
|
||||
i = i->succ;
|
||||
j = j->succ;
|
||||
}
|
||||
else
|
||||
{
|
||||
j = j->next;
|
||||
if(j==T->succ)
|
||||
p = i; //记下重新开始匹配时i的起点
|
||||
}
|
||||
}
|
||||
|
||||
if(!j)
|
||||
{
|
||||
for(count=1,q=S->succ; q!=p; count++,q=q->succ)
|
||||
; //找出第一个结点匹配的位置
|
||||
return count;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status AssignLString(LString *S, char *s)
|
||||
{
|
||||
int i;
|
||||
LString pre, p;
|
||||
|
||||
*S = (LString)malloc(sizeof(strLNode));
|
||||
if(!(*S))
|
||||
exit(OVERFLOW);
|
||||
(*S)->next = (*S)->succ = NULL;
|
||||
|
||||
for(i=0,pre=*S; i<strlen(s); i++)
|
||||
{
|
||||
p = (LString)malloc(sizeof(strLNode));
|
||||
if(!p)
|
||||
exit(OVERFLOW);
|
||||
p->chdata = s[i];
|
||||
p->next = pre;
|
||||
p->succ = pre->succ;
|
||||
pre->succ = p;
|
||||
pre = pre->succ;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status PrintLString(LString S)
|
||||
{
|
||||
LString p;
|
||||
|
||||
if(!S)
|
||||
return ERROR;
|
||||
|
||||
for(p=S->succ; p; p=p->succ)
|
||||
printf("%c", p->chdata);
|
||||
|
||||
return OK;
|
||||
}
|
||||
80
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.30-main .c
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c"//**▲04 串**//
|
||||
|
||||
/* 函数原型 */
|
||||
Status Algo_4_30(SString S, SString Sub, int *pos);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s = "abcdeabcabcbcdefbcdefefghefgh";
|
||||
SString Sub, S;
|
||||
int pos;
|
||||
|
||||
StrAssign_Sq(S, s);
|
||||
printf("主串...\n");
|
||||
printf("S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n\n");
|
||||
|
||||
printf("首个最长不重复子串...\n");
|
||||
printf("Sub = ");
|
||||
Algo_4_30(S, Sub, &pos);
|
||||
StrPrint_Sq(Sub);
|
||||
printf("\n");
|
||||
printf("Sub 在 S中首次出现的位置为 %d\n", pos);
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃题4.30:求首次出现的最长重复子串及其位置┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━*/
|
||||
/*
|
||||
**此处的最长重复子串有三层含义:
|
||||
**第一:此子串在所有重复子串中是首个出现且最长的;
|
||||
**第二:子串间可以重叠,比如求取abcabca的结果为abca;
|
||||
**第三:子串内可以重复,如求取aaaa的结果为aaa。
|
||||
*/
|
||||
Status Algo_4_30(SString S, SString Sub, int *pos) //0号单元
|
||||
{
|
||||
int i, j, k, len, start, end;
|
||||
|
||||
if(S[0]<2) //主串元素个数不能少于2
|
||||
return ERROR;
|
||||
|
||||
Sub[0] = 0;
|
||||
|
||||
for(k=1; k<S[0]; k++) //范围从1到S[0]-1
|
||||
{
|
||||
i = k;
|
||||
j = k+1;
|
||||
|
||||
while(j<=S[0] && S[i]!=S[j])
|
||||
j++; //找到首个潜在的循环起点
|
||||
|
||||
if(j<=S[0])
|
||||
{
|
||||
start = i;
|
||||
end = j;
|
||||
len = 0;
|
||||
while(j<=S[0] && S[i]==S[j])
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
len++;
|
||||
}
|
||||
|
||||
if(len>Sub[0] && start+len-1>=end-1 ) //保证连续性和最长这两个特性
|
||||
{
|
||||
*pos = start;
|
||||
SubString_Sq(Sub, S, start, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(Sub[0])
|
||||
return OK;
|
||||
else
|
||||
return ERROR;
|
||||
}
|
||||
162
▼配套习题解析/▼04 串/▼习题测试文档-04/Question-4.31-main .c
Normal file
@@ -0,0 +1,162 @@
|
||||
#include <stdio.h>
|
||||
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../../▲课本算法实现/▲04 串/01 SequenceString/SequenceString.c"//**▲04 串**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define Sl 2000
|
||||
|
||||
/* 类型定义 */
|
||||
typedef struct
|
||||
{
|
||||
SString String; //某个最长的公共
|
||||
int start; //字符串起点
|
||||
}PString;
|
||||
typedef struct
|
||||
{
|
||||
PString Sub[MAXSTRLEN+1];
|
||||
int count;
|
||||
}StringSet; //满足条件的子串集合
|
||||
|
||||
/* 函数原型 */
|
||||
Status Algo_4_31(SString S, SString T, StringSet *Set_s, StringSet *Set_t);
|
||||
Status StringSetPrint(StringSet Set);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s = "abcd*lokis***hyuij**vfgh*lokis****yu*mklng***u****wy*c*vdgry*pklnh";
|
||||
char *t = "-vdgry--vfgh-hyuij---abcd-pklnh---yu----lokis-----uio-u--wy---mklng-c ";
|
||||
SString S, T;
|
||||
StringSet Set_s, Set_t;
|
||||
|
||||
printf("初始化...\n");
|
||||
StrAssign_Sq(S, s);
|
||||
StrAssign_Sq(T, t);
|
||||
printf("S = ");
|
||||
StrPrint_Sq(S);
|
||||
printf("\n");
|
||||
printf("T = ");
|
||||
StrPrint_Sq(T);
|
||||
printf("\n\n");
|
||||
|
||||
printf("求取公共子串的集合...\n");
|
||||
Algo_4_31(S, T, &Set_s, &Set_t);
|
||||
printf("\n");
|
||||
|
||||
printf("输出 S 中公共子串信息...\n");
|
||||
StringSetPrint(Set_s);
|
||||
printf("\n");
|
||||
|
||||
printf("输出 T 中公共子串信息...\n");
|
||||
StringSetPrint(Set_t);
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━━┓
|
||||
┃题4.31:最长公共子串┃
|
||||
┗━━━━━━━━━━*/
|
||||
/* 结构StringSet保存串S和串T所有的最长公共子串及其起始位置和数量 */
|
||||
Status Algo_4_31(SString S, SString T, StringSet *Set_s, StringSet *Set_t)
|
||||
{
|
||||
int i, j; //i标记S,j标记T
|
||||
int m, n;
|
||||
int k, flag;
|
||||
int len[MAXSTRLEN+1][MAXSTRLEN+1];
|
||||
|
||||
if(!S[0] || !T[0]) //有字符串为空
|
||||
return ERROR;
|
||||
|
||||
for(m=0; m<=T[0]; m++) //初始化首列为0
|
||||
len[m][0] = 0;
|
||||
for(n=0; n<=S[0]; n++) //初始化首行为0
|
||||
len[0][n] = 0;
|
||||
|
||||
m = T[0]+1;
|
||||
n = 1;
|
||||
while(n<=S[0])
|
||||
{
|
||||
m>1 ? m-- : n++;
|
||||
|
||||
for(i=m,j=n; i<=T[0]&&j<=S[0]; i++,j++)
|
||||
{
|
||||
if(T[i]==S[j])
|
||||
len[i][j] = len[i-1][j-1] + 1;
|
||||
else
|
||||
len[i][j] = 0;
|
||||
|
||||
if(len[i][j]>len[m-1][n-1])
|
||||
len[m-1][n-1] = len[i][j];
|
||||
|
||||
if(len[i][j]>len[0][S[0]])
|
||||
len[T[0]][0] = len[0][S[0]] = len[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
if(!len[0][S[0]])//两字符串无最长公共子串
|
||||
return ERROR;
|
||||
|
||||
m = T[0]+1;
|
||||
n = 1;
|
||||
(*Set_s).count = (*Set_t).count = 0;
|
||||
|
||||
while(n<=S[0])
|
||||
{
|
||||
m>1 ? m-- : n++;
|
||||
|
||||
if(len[m-1][n-1]==len[0][S[0]])//存在最长公共子串
|
||||
{
|
||||
for(i=m,j=n; i+len[0][S[0]]-1<=T[0]&&j+len[0][S[0]]-1<=S[0]; i++,j++)
|
||||
{
|
||||
if(len[i+len[0][S[0]]-1][j+len[0][S[0]]-1]==len[0][S[0]])//满足条件的字符串起点
|
||||
{
|
||||
for(k=1,flag=0; k<=(*Set_t).count; k++)//是否已加入T中
|
||||
{
|
||||
if((*Set_t).Sub[k].start==i)
|
||||
{
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flag)//收集T中出现的最长公共字符串
|
||||
{
|
||||
(*Set_t).count++;
|
||||
(*Set_t).Sub[(*Set_t).count].start = i;
|
||||
SubString_Sq((*Set_t).Sub[(*Set_t).count].String, T, i, len[T[0]][0]);
|
||||
}
|
||||
|
||||
for(k=1,flag=0; k<=(*Set_s).count; k++)//是否已加入S中
|
||||
{
|
||||
if((*Set_s).Sub[k].start==j)
|
||||
{
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flag)//收集S中出现的最长公共字符串
|
||||
{
|
||||
(*Set_s).count++;
|
||||
(*Set_s).Sub[(*Set_s).count].start = j;
|
||||
SubString_Sq((*Set_s).Sub[(*Set_s).count].String, S, j, len[0][S[0]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status StringSetPrint(StringSet Set)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
for(k=1; k<=Set.count; k++)
|
||||
{
|
||||
printf("第 %2d 个位置:", Set.Sub[k].start);
|
||||
StrPrint_Sq(Set.Sub[k].String);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
192
▼配套习题解析/▼04 串/▼第04章 串.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# 第4章 串
|
||||
|
||||
## 一、基础知识题
|
||||
|
||||
### 4.1 简述空串和空格串(或称空格符串)的区别。
|
||||
|
||||
> 一个空字符为:‘\0’ ,一个空格字符为:‘ ’ 。空串是只包含一个空字符的字符串,其长度为0。
|
||||
> 空格串是除了在结尾包含空字符外,还包含若干空格字符的字符串,统计其长度时,要将除空字符外的字符个数都计算在内。
|
||||
|
||||
### 4.2 对于教科书4.1节中所述串的各个基本操作,讨论是否可由其他基本操作构造而得,如何构造?
|
||||
|
||||
> 对于串操作中的最小操作子集,即串赋值(StrAssign)、串比较(StrCompare)、求串长(StrLength)、串联接(Conact)以及求子串(SubString)5种操作不可由其他操作来实现。
|
||||
> 其他串操作则可利用串的最小操作子集实现。
|
||||
|
||||
### 4.3 设s = ‘I AM A STUDENT’,t = ‘GOOD’,q = ‘WORKER’。
|
||||
##### 求:StrLength(s),StrLength(t),SubString(s, 8, 7),SubString(t, 2, 1),Index(s, ‘A’),Index(s, t),Replace(s, ‘STUDENT’, q),Concat(SubString(s, 6, 2), Concat(t, SubString(s, 7, 8)))。
|
||||
|
||||
> StrLength(s) = 14;
|
||||
> StrLength(t) = 4;
|
||||
> SubString(s, 8, 7) = ‘STUDENT’;
|
||||
> SubString(t, 2, 1) = ‘O’;
|
||||
> Index(s, ‘A’) = 3;
|
||||
> Index(s, t) = 0;
|
||||
> Replace(s, ‘STUDENT’, q) = ‘I AM A WORKER’;
|
||||
> Concat(SubString(s, 6, 2), Concat(t, SubString(s, 7, 8))) = ‘A GOOD STDENT’.
|
||||
|
||||
### 4.4 已知下列字符串
|
||||
##### a = ‘THIS’, f = ‘A SAMPLE’, c = ‘GOOD’, d = ‘NE’, b = ‘ ’.
|
||||
##### s = Concat(a, Concat(SubString(f, 2, 7), Concat(b, SubString(a, 3, 2)))),
|
||||
##### t = Replace(f, SubString(f, 3, 6), c),
|
||||
##### u = Concat(SubString(c, 3, 1), d),
|
||||
##### g = ‘IS’,
|
||||
##### v = Concat(s, Concat(b, Concat(t, Concat(b, u)))),
|
||||
##### 试问:s,t,v,StrLength(s),Index(v, g),Index(u, g)各是什么?
|
||||
|
||||
> s = ‘THIS SAMOLE IS’;
|
||||
> t = ‘A GOOD’;
|
||||
> v = ‘THIS SAMPLE IS A GOOD ONE’;
|
||||
> StrLength(s) = 14;
|
||||
> Index(v, g) = 3;
|
||||
> Index(u, g) = 0.
|
||||
|
||||
### 4.5 试问执行以下函数会产生怎样的输出结果?
|
||||
|
||||
```c
|
||||
void demonstrate()
|
||||
{
|
||||
StrAssign(s, ‘THIS IS A BOOK’);
|
||||
Replace(s, SubString(s, 3, 7), ‘ESE ARE’);
|
||||
StrAssign(t, Concat(s, ‘S’));
|
||||
StrAssign(u, ‘XYXYXYXYXYXY’);
|
||||
StrAssign(v, SubString(u, 6, 3));
|
||||
StrAssign(w, ‘W’);
|
||||
printf(‘t=’, t, ‘v=’, v, ‘u=’, Replace(u, v, w));
|
||||
}//demonstrate
|
||||
```
|
||||
|
||||
> t=‘THESE ARE BOOKS’,v=‘YXY’,u=‘XWXWXW’.
|
||||
|
||||
### 4.6 已知:s = ‘(XYZ)+*’,t = ‘(X+Z)*Y’。试利用联接、求子串和置换等基本运算,将s转化为t。
|
||||
|
||||
> S1 = SubString(s, 3, 1); //S1 = ‘Y’
|
||||
> S2 = SubString(s, 6, 1); //S2 = ‘+’
|
||||
> Replace(s, S1, S2); //s = ‘(X+Z)+*’
|
||||
> Concat(S3, s, S1); //S3 = ‘(X+Z)+*Y’
|
||||
> Concat(t, SubString(S3, 1, 5), SubString(S3, 7, 2));
|
||||
|
||||
### 4.7 令s = ‘aaab’,t = ‘abcabaa’,u = ‘abcaabbabcabaacbacba’。试分别求出它们的next函数值和nextval函数值。
|
||||
|
||||
> **s**
|
||||
|
||||

|
||||
|
||||
> **t**
|
||||
|
||||

|
||||
|
||||
> **u**
|
||||
|
||||

|
||||
|
||||
### 4.8 已知主串s = ‘ADBADABBAABADABBADADA’,模式串pat = ‘ADABBADADA’,写出模式串的nextval函数值,并由此画出KMP算法匹配的全过程。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 4.9 在以链表存储串值时,存储密度是结点大小和串长的函数。假设每个字符占一个字节,每个指针占4个字节,每个结点的大小为4的整数倍,已知串长的分布函数为f(l)且,求结点大小为4k,串长为l时的存储密度d(4k, l)(用公式表示)。
|
||||
|
||||

|
||||
|
||||
## 二、算法设计题
|
||||
|
||||
```c
|
||||
在编写4.10至4.14题的算法时,请采用StringType数据类型:
|
||||
StringType是串的一个抽象数据类型,它包含以下五种基本操作:
|
||||
|
||||
void StrAssign (StringType &t, StringType s)
|
||||
//将s的值赋给t。s的实际参数可以是串变量或者串常量(如:‘abcd’)
|
||||
|
||||
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的子串,否则返回空串
|
||||
```
|
||||
|
||||
### 4.10 编写对串求逆的递推算法。
|
||||
|
||||
>[Question-4.10-main.c](▼习题测试文档-04/Question-4.10-main.c)
|
||||
|
||||
### 4.11 编写算法,求得所有包含在串s中而不包含在串t中的字符(s中重复的字符只选一个)构成的新串r,以及r中每个字符在s中第一次出现的位置。
|
||||
|
||||
>[Question-4.11-main.c](▼习题测试文档-04/Question-4.11-main.c)
|
||||
|
||||
### 4.12 编写一个实现串的置换操作Replace(&S, T, V)的算法。
|
||||
|
||||
>[Question-4.12-main.c](▼习题测试文档-04/Question-4.12-main.c)
|
||||
|
||||
### 4.13 编写算法,从串s中删除所有和串t相同的子串。
|
||||
|
||||
>[Question-4.13-main.c](▼习题测试文档-04/Question-4.13-main.c)
|
||||
|
||||
### 4.14 利用串的基本操作以及栈和集合的基本操作,编写“由一个算术表达式的前缀式求后缀式”的递推算法(假设前缀式不含语法错误)。
|
||||
|
||||
>[Question-4.14-main.c](▼习题测试文档-04/Question-4.14-main.c)
|
||||
|
||||
>> ### 在编写4.15至4.20题的算法时,请采用教科书4.2.1节中所定义的定长顺序存储表示,而不允许调用串的基本操作。
|
||||
|
||||
### 4.15 编写算法,实现串的基本操作StrAssign(&T, chars)。
|
||||
### 4.16 编写算法,实现串的基本操作StrCompare(S, T)。
|
||||
### 4.17 编写算法,实现串的基本操作Replace(&S, T, V)。
|
||||
|
||||
>[Question-4.15~4.17-main.c](▼习题测试文档-04/Question-4.15~4.17-main.c)
|
||||
|
||||
### 4.18 编写算法,求串s所含不同字符的总数和每种字符的个数。
|
||||
|
||||
>[Question-4.18-main .c](▼习题测试文档-04/Question-4.18-main%20.c)
|
||||
|
||||
### 4.19 在串的定长顺序存储结构上直接实现4.11题要求的算法。
|
||||
|
||||
>[Question-4.19-main .c](▼习题测试文档-04/Question-4.19-main%20.c)
|
||||
|
||||
### 4.20 编写算法,从串s中删除所有和串t相同的子串。
|
||||
|
||||
>[Question-4.20-main .c](▼习题测试文档-04/Question-4.20-main%20.c)
|
||||
|
||||
### 4.21 假设以结点大小为1(且附设头结点)的链表结构表示串。试编写实现下列六种串的基本操作StrAssign,StrCopy,StrCompare,StrLength,Concat和SubString的函数。
|
||||
|
||||
>[Question-4.21-main .c](▼习题测试文档-04/Question-4.21-main%20.c)
|
||||
|
||||
### 4.22 假设以块链结构表示串。试编写将串s插入到串t中某个字符之后的算法(若串t中不存在此字符,则将串s联接在串t的末尾)。
|
||||
|
||||
>[Question-4.22-main .c](▼习题测试文档-04/Question-4.22-main%20.c)
|
||||
|
||||
### 4.23 假设以块链结构作串的存储结构。试编写判别给定串是否具有对称性的算法,并要求算法的时间复杂度为O(StrLength(S))。
|
||||
|
||||
>[Question-4.23-main .c](▼习题测试文档-04/Question-4.23-main%20.c)
|
||||
|
||||
>> ### 在编写4.24至4.26题的算法时,请采用教科书4.2.2节中所定义的堆分配存储表示。
|
||||
|
||||
### 4.24 试写一算法,在串的堆存储结构上实现串基本操作Concat(&T, s1,s2)。
|
||||
### 4.25 试写一算法,实现堆存储结构的串的置换操作Replace(&S, T, V)。
|
||||
### 4.26 试写一算法,实现堆存储结构的串的插入操作 StrInsert(&S, pos, T)。
|
||||
|
||||
>[Question-4.24~4.26-main .c](▼习题测试文档-04/Question-4.24~4.26-main%20.c)
|
||||
|
||||
### 4.27 当以教科书4.2.1节中定义的定长顺序结构表示串时,可如下所述改进定位函数的算法:先将模式串t中的第一个字符和最后一个字符与主串s中相应的字符比较,在两次比较都相等之后,再依次从t的第二个字符逐个比较。这样做可以克服算法Index(算法4.5)在求模式串’a<sup>k</sup>b’(a<sup>k</sup>表示连续k个字符’a’) 在主串’a<sup>n</sup>b’(k≤n)中的定位函数时产生的弊病。试编写上述改进算法,并比较这两种算法在作Index(’a<sup>n</sup>b’,’a<sup>k</sup>b’)运算时所需进行的字符间的比较次数。
|
||||
|
||||
>[Question-4.27-main .c](▼习题测试文档-04/Question-4.27-main%20.c)
|
||||
|
||||
### 4.28 假设以结点大小为1(带头结点)的链表结构表示串,则在利用next函数值进行串匹配时,在每个结点中需设三个域:数据域chdata、指针域succ和指针域next。其中chdata域存放一个字符;succ域存放指向同一链表中后继结点的指针;next域在主串中存放指向同一链表中前驱结点的指针;在模式串中,存放指向当该结点的字符与主串中的字符不等时,在模式串中下一个应进行比较的字符结点(即与该字符的next函数值相对应的字符结点)的指针,若该节点字符的next函数值为0,则其next域的值应指向头结点。试按上述定义的结构改写求模式串的next函数值的算法。
|
||||
### 4.29 试按4.28题定义的结构改写串匹配的改进算法(KMP算法)。
|
||||
|
||||
>[Question-4.28~4.29-main .c](▼习题测试文档-04/Question-4.28~4.29-main%20.c)
|
||||
|
||||
### 4.30 假设以定长顺序存储结构表示串,试设计一个算法,求串s中出现的第一个最长重复子串及其(第一次出现的)位置,并分析你的算法的时间复杂度。
|
||||
|
||||
>[Question-4.30-main .c](▼习题测试文档-04/Question-4.30-main%20.c)
|
||||
|
||||
### 4.31 假设以定长顺序存储结构表示串,试设计一个算法,求串s和串t的一个最长公共子串,并分析你的时间复杂度。若要求第一个出现的最长公共子串(即它在串s和串t的最左边的位置上出现)和所有的最长公共子串,讨论你的算法能否实现。
|
||||
|
||||
>[Question-4.31-main .c](▼习题测试文档-04/Question-4.31-main%20.c)
|
||||
|
||||
|
||||