文档库 最新最全的文档下载
当前位置:文档库 › 数据结构(第二版)习题答案第4章

数据结构(第二版)习题答案第4章


4章字符串、数组和特殊矩阵


4.1稀疏矩阵常用的压缩存储方法有( 三元组顺序存储 )和(十字链表 )两种。
4.2设有一个 10 × 10的对称矩阵 A采用压缩方式进行存储,存储时以按行优先的顺序存
储其下三角阵,假设其起始元素 a00的地址为 1,每个数据元素占 2个字节,则 a65的地址为
( 53 )。
4.3若串 S =“software”,其子串的数目为( 36 )。
4.4常对数组进行的两种基本操作为( 访问数据元素 )和( 修改数组元素 )。
4.5 要计算一个数组所占空间的大小,必须已知(数组各维数)和(每个元素占用的空
间)。
4.6对于半带宽为 b的带状矩阵,它的特点是:对于矩阵元素 aij,若它满足(|i-j|>b),
则 aij = 0。
4.7字符串是一种特殊的线性表,其特殊性体现在( 该线性表的元素类型为字符 )。
4.8试编写一个函数,实现在顺序存储方式下字符串的 strcompare(S1,S2)运算。
【答】:
#include
#include
#define MAXSIZE 100
typedef struct{


char str[MAXSIZE];

int length;
}seqstring;
/* 函数 strcompare()的功能是:当 s1>s2时返回 1,当 s1==s2时返回 0,当 s1int strcompare(seqstring s1,seqstring s2)
{ int i,m=0,len;

len=s1.lengthfor(i=0;i<=len;i++)
if(s1.str[i]>s2.str[i])


{m=1;break;}
else if(s1.str[i]{m=-1;break;}


return m;
}
int main()
{ seqstring s1,s2;


int i,m;
printf("input char to s1:\n");



gets(s1.str);
s1.length=strlen(s1.str);
printf("input char to s2:\n");
gets(s2.str);
s2.length=strlen(s2.str);
m=strcompare(s1,s2);
if(m==1) printf("s1>s2\n");
else if(m==-1) printf("s2>s1\n");
else if(m==0) printf("s1=s2\n");


}

4.9试编写一个函数,实现在顺序存储方式下字符串的
replace(S,T1,T2)运算。
【参考程序
1】:
/*本程序用来在顺序存储下用快速匹配模式实现在字符串
S中用
T2替换所有
T1出现的可
能*/
#include
#include
#include
# define maxsize 100
typedef struct{

char str[maxsize];

int length ;
} seqstring;
//求
next[]函数
void getnext(seqstring*p,int next[])
{int i,j;


next[0]=-1;
i=0;j=-1;
while(ilength)
{


if(j==-1||p->str[i]==p->str[j])
{++i;++j;next[i]=j;}
else


j=next[j];
}
}


//快速模式匹配算法
int kmp(seqstring*t,seqstring*p,int next[],int temppos)
{int i,j;



i=temppos,j=0;
while (ilength && jlength)
{


if(j==-1||t->str[i]==p->str[j])
{i++; j++;}
else j=next[j];


}
if (j==p->length) return (i-p->length);
else return(-1);


}
//替换函数
void takeplace(seqstring*S,seqstring*T1,seqstring*T2)
{

int next[maxsize],temppos=0,pos,i;
int lent1,le

nt2;
lent1=strlen(T1->str); //求
T1串长度
lent2=strlen(T2->str); //求
T2串长度
getnext(T1,next);//求
T1串的
next[]向量
do
{


pos=kmp(S,T1,next,temppos); //快速模式匹配
temppos=pos+T1->length;
if (pos!=-1) //匹配成功
{


if (lent1>lent2) //T1串长度大于
T2串长度
{
for (i=temppos;ilength;i++) //前移


S->str[i-lent1+lent2]=S->str[i];
for(i=0;ilength;i++) //替换
S->str[pos+i]=T2->str[i];
S->length-=lent1-lent2; //修改长度


}

else
if (lent2>lent1) //T2串长度大于
T1串长度
{

for (i=S->length-1;i>=temppos;i--) //后移留空
S->str[i+lent2-lent1]=S->str[i];
for(i=0;ilength;i++) //替换


S->str[pos+i]=T2->str[i];
S->length+=lent2-lent1; //修改长度
}
else //T1长度与
T2长度相等
{ for(i=0;ilength;i++)
S->str[pos+i]=T2->str[i];
}
temppos=pos+T2->length; //修改下一次模式匹配的起点位置

}
}while(pos!=-1);
S->str[S->length]='\0';
}
int main()
{ seqstring*S,*T1,*T2;


printf("\n\n本程序用来实现字符串替换,将
S中用
T2替换
T1所有出现\nThis program
is used for characters batch takeing place,The T1 characters batch will take place all the T2's
appearances in characters batch S: \n\n");

printf("请输入
S中的字符(plese input characters batch S:)\n");
S=(seqstring*)malloc(sizeof(seqstring));
T1=(seqstring*)malloc(sizeof(seqstring));
T2=(seqstring*)malloc(sizeof(seqstring));
scanf("%s",S->str);
S->length=strlen(S->str);
printf("输入要被替换的串
(input T1):\n");
scanf("%s",T1->str);
T1->length=strlen(T1->str);
printf("输入替换串
(input T2):\n");
scanf("%s",T2->str);
T2->length=strlen(T2->str);
takeplace(S,T1,T2);
printf("替换后的字符串为:\n");
printf("%s\n",S->str);
free(S);
free(T1);
free(T2);


}
【参考程序
2】:


#include


#define MAXSIZE 100

typedef struct{
char str[MAXSIZE];
int length;
}seqstring;

void getnext(seqstring p,int next[]) //求模式的
next函数

{int i,j;
next[0]=-1;
i=0;
j=-1;
while(i

{if(j==-1||p.str[i]==p.str[j])
{++i;++j;next[i]=j;}
else j=next[j];
}
}
void replace(seqstring *s,seqstring t1,seqstring t2,int next[])


{int i,j,k,c,m;
i=0;j=0;k=0;
while(ilength)
{ j=0;


while(ilength&&j{if(j==-1||s->str[i]==t1.str[j])
{i++; j++;}


else j=next[j];
}
if(j==t1.length) //匹配成功


{ c=i-t1.length;
if(t1.length==t2.length) //两串长度相等直接替换
for(k=0;ks->str[c+k]=t2.str[k];
else if(t1.length{ for(m=s->length-1;m>i-1;m--)
s->str[t2.length-t1.length+m]=s->str[m]; //后移留空
for(k=0;k
s->str[c+k]=t2.str[k];
s->length=s->length-t1.length+t2.length;
s->str[s->length]='\0';

}


else
{ for(m=i-1;mlength;m++) //前移

s->str[m-t1.length+t2.length]=s->str[m];
for(k=0;k
s->str[c+k]=t2.str[k];
s->length=s->length-t1.length+t2.length;
s->str[s->length]='\0';

}

i=i+t2.length-t1.length;
}
i++;

}
}
int main()

{ int next[MAXSIZE];
seqstring s,t1,t2;
printf("Input string s:"); //输入主串
gets(s.str);
printf("\nInput string t1:"); //输入模式串
gets(t1.str);
printf("\nInput string t2:"); //输入拟替换的串
gets(t2.str);
s.length=strlen(s.str);
t1.length=strlen(t1.str);
t2.length=strlen(t2.str);
getnext(t1,next);
replace(&s,t1,t2,next);
puts(s.str);
}

4.10试编写一个函数,实现在链式存储方式下字符串的
strcompare(S1,S2)运算。
【参考程序】:
/*建立字符串链式存储结构文件
linkstring.h*/
#include
#include
typedef struct node
{

char data;

struct node *next;

} linkstrnode;


typedef linkstrnode *linkstring;
/*---------------------------------------*/
/* 尾插法建立单链表 */
/*---------------------------------------*/
void strcreate(linkstring *S)
{ char ch;

linkstrnode *p,*r;
*S=NULL; r=NULL;
while ((ch=getchar())!='\n')


{ p=(linkstrnode *)malloc(sizeof(linkstrnode));
p->data=ch; /*产生新结点*/
if (*S==NULL) /*新结点插入空表
*/


{ *S=p; r=p;}
else {r->next=p;


r=p;}
}
if (r!=NULL) r->next=NULL; /*处理表尾结点指针域
*/

}
/*---------------------------------------------*/
/*输出单链表的内容 */
/*---------------------------------------------*/
void print(linkstring head)
{


linkstrnode *p;
p=head;
while (p)


{printf("%c-->",p->data);

p=p->next;
}
printf("\n");


}

#include “linkstring.h”
int strcompare(linkstrnode*S1,linkstrnode*S2)
{

while(S1&&S2)
{ if(S1->data>S2->data)
return 1;
else if(S1->datadata)



return -1;
S1=S1->next;
S2=S2->next;

}
if(S1) return 1;
else if(S2) return -1;
return 0;
}
int main()

{
linkstring s1,s2;
int k;
printf("\nPlease input s1:");
strcreate(&s1); /*建立字符串
s1*/
print(s1);
printf("\nPlease input s2:");
strcreate(&s2); /*建立字符串
s2*/
print(s2);
k=strcompare(s1,s2);
if (k==1) printf("s1>s2");
else

if (k==-1)printf("s1else
printf("s1==s2");
}

4.11试编写一个函数,实现在链式存储方式下字符串的
replace(S,T1,T2)运算。
/*题目:链式存储方式下字符串的
replace(S,T1,T2)运算*/
【参考程序】:
#include "linkstring.h"
/*单链表拷贝函数
*/
linkstring copy(linkstring head)
{ linkstring L=NULL,r=NULL,s,p;


p=head;
while(p)

{s=(linkstring)malloc(sizeof(linkstrnode));
s->data=p->data;
if (L==NULL) L=r=s;
else

{r->next=s;


r=s;
}
p=p->next;


}
if (r!=NULL) r->next=NULL;
return L;


}
/*----------------------

--------------------------*/
/* 在字符串
S中用
T2替换
T1 */
/*------------------------------------------------*/
linkstring replace(linkstring S,linkstring T1,linkstring T2)
{linkstring p,q,r,s,pre,temp,pos;


int flag=1;
if (S==NULL|| T1==NULL ) return S; /*若
S为空或
T1为空,则原串不变*/
pre=NULL;
pos=S; /*pos表示可能的
T1串在
S中的起始位置*/
while (pos && flag) /*flag表示
S中存在
T1*/
{ p=pos;


q=T1;
while ( p&&q ) /*从
pos开始找子串
T1*/
{ if (p->data==q->data)


{ p=p->next;q=q->next;}
else


{pre=pos;
pos=pos->next;
p=pos;
q=T1;


}
}


if (q!=NULL) flag=0; /*未找到子串
T1*/
else
{ flag=1; /*找到了子串
T1,用
T2代替
T1*/


r=pos;
while (r!=p) /*首先删除子串
T1,最后
p指向删除串
T1的下一个结点*/
{s=r;


r=r->next;
free(s);
}
if (T2!=NULL) /*T2不为空*/



{ temp=r=copy(T2); /*复制一个
T2串*/
while (r->next!=NULL) /*找
temp串的尾结点*/

r=r->next;
r->next=p;
if (pre==NULL) /*如果
T1出现在
S的链头*/

S=temp; /*新串成为链首
*/
else /*T1不是链首串
*/

pre->next=temp;
pre=r;
pos=p; /*从
p开始继续找子串
T1*/
}

else /*原
T2子串为空
*/
{ if (pre==NULL) /*T1为链首串
*/
S=p;
else
pre->next=p;
pos=p;
}

}
}
return S;


}
int main()
{linkstring S,T1,T2;


printf("\nPlease input S:");
strcreate(&S); /*建立字符串
S*/
print(S);
printf("\nPlease input T1:");
strcreate(&T1); /*建立字符串
T1*/
print(T1);
printf("\nPlease input T2:");
strcreate(&T2); /*建立字符串
T2*/
print(T2);
S=replace(S,T1,T2);
printf("\nThe result is:\n");
print(S);


}

4.12已知如下字符串,求它们的
next数组值:
(1)“bbdcfbbdac”

【答】:-1010001230

(2)“aaaaaaa”
【答】:-1012345
(3)“babbabab”
【答】:-10011232
4.13已知正文
t =“ababbaabaa”,模式
p =“aab”,试使用
KMP快速模式匹配算法寻找
p

t中首次出现的起始位置,给出具体的匹配过程分析。
【答】:模式
p的
next向量如下表所示:
0 1 2


a a b
-1 0 1

第一趟匹配:


0 1 2 3 4 5 6 7 8 9

a b a b b a a b a a
a a

i=1,j=1,匹配失败,此时
j取
next[1]=0,即下一趟匹配从
i=1,j=0开始;
第二趟匹配:


0 1 2 3 4 5 6 7 8 9

a b a b b a a b a a
a

i=1,j=0,匹配失败,此时
j=next[0]=-1,下一趟匹配从
i=2,j=0开始;
第三趟匹配:


0 1 2 3 4 5 6 7 8 9

a b a b b a a b a a
a a

i=3,j=1,匹配失败,此时
j=next[1]=0,下一趟匹配从
i=3,j=0开始;
第四趟匹配:


0 1 2 3 4 5 6 7 8 9

a b a b b a a b a a
a

i=3,j=0,匹配失败,此时
j=next[0]=-1,下一趟匹配从
i=4,j=0

开始;
第五趟匹配:


0 1 2 3 4 5 6 7 8 9

a b a b b a a b a a
a

i=4,j=0,匹配失败,此时
j=next[0]=-1,下一趟匹配从
i=5,j=0开始;
第五趟匹配:


0 1 2 3 4 5 6 7 8 9


a b a b b a a b a a
a a b

i=8,j=3,匹配完成,表明匹配成功的位置是:
i-j=5。


4.14已知三维数组
A[3][2][4],数组首地址为
100,每个元素占用
1个存储单元,分别计
算数组元素
A[0][1][2]在按行优先和按列优先存储方式下的地址。
【答】:
A[0][1][2]按行优先方式在内存的存储地址为:
100+0*8+1*4+2=106
A[0][1][2]按列优先方式在内存的储储地址为:
100+2*6+1*3+0*8=115

4.15已知两个稀疏矩阵
A和
B,其行数和列数均对应相等,编写一个函数,计算
A和
B
之和,假设稀疏矩阵采用三元组表示。
【参考程序
1】:
#include
typedef struct {
int data[100][100];
int m,n; /*分别存放稀疏矩阵的行数、列数和非零元素的个数
*/

} matrix;
typedef int spmatrix[100][3]; //三元组存储结构
spmatrix c;


void add(spmatrix a,spmatrix b,spmatrix c) //基于三元组结构的矩阵相加算法

{int i,j,k,t,r;
i=j=k=1;
while(i<=a[0][2]&&j<=b[0][2])
{if(a[i][0]

{
c[k][0]=a[i][0];
c[k][1]=a[i][1];
c[k][2]=a[i][2];
i++;k++;


}
else
if(a[i][0]>b[j][0]||(a[i][0]==b[j][0]&&a[i][1]>b[j][1]))


{
c[k][0]=b[j][0];
c[k][1]=b[j][1];
c[k][2]=b[j][2];
j++;k++;


}
else
if(a[i][0]==b[j][0]&&(a[i][1]==b[j][1]) )


{
c[k][0]=a[i][0];


c[k][1]=a[i][1];
c[k][2]=a[i][2]+b[j][2];
i++;j++;
if (c[k][2]!=0 ) k++; /*如果相加的和不为
0,则生成一个有效项
*/


}
}
while(j<=b[0][2])
{ c[k][0]=b[j][0];


c[k][1]=b[j][1];
c[k][2]=b[j][2];
j++;k++;


}
while(i<=a[0][2])


{
c[k][0]=a[i][0];
c[k][1]=a[i][1];
c[k][2]=a[i][2];
i++;k++;


}
c[0][0]=a[0][0];
c[0][1]=a[0][1];
c[0][2]=k-1;


}

//函数
compressmatrix将普通矩阵存储转换为三元组存储结构
void compressmatrix(matrix *A , spmatrix B)

{
int i, j, k;
k=1;
for ( i=0; im; i++)


for (j=0;jn; j++)
if (A->data[i][j] !=0)


{ B[k][0]=i;
B[k][1]=j;
B[k][2]=A->data[i][j];
k++;


}
B[0][0]=A->m;
B[0][1]=A->n;
B[0][2]=k-1;



i=0;
printf("the spmatrix is:\n");
while(i<=B[0][2])


{ printf("%d%5d%5d\n",B[i][0],B[i][1],B[i][2]);
i++;

}
}
void creat(int r,int w,matrix *s)

{
int i,j,data;
printf("input numbers:\n");
for(i=0;i

for(j=0;j
{
scanf("%d",&data);
s->data[i][j]=data;

}
printf("the array is:\n");
for(i=0;i

{ for(j=0;jprintf("%5d",s->data[i][j]);
printf("\n");

}
s->m=r;
s->n=w;


}
int main()

{matrix p,q;
spmatrix a,b,c;
int r,w,i

;
i=0;
printf("input r,w:"); /*输入行和列*/
scanf("%d%d",&r,&w);
creat(r,w,&p);
creat(r,w,&q);
compressmatrix(&p,a);
compressmatrix(&q,b);
i=0;
add(a,b,c);
printf("the spmatrix c is:\n");



while(i<=c[0][2])
{ printf("%d%5d%5d\n",c[i][0],c[i][1],c[i][2]);
i++;
}
}


程序运行时先输入矩阵的行和列,然后按普通矩阵格式输入矩阵值,一组程序测试用例运
行结果如下图:


【参考程序
2】:


#include
#include
#define MAX 100
typedef struct{

int data[MAX][3];

int m,n,value;
}matrix;
matrix *Input(matrix *A)
{ int i,j;

A = (matrix*)malloc(sizeof(matrix));
scanf("%d%d%d",&A->m,&A->n,&A->value);
A->data[0][0] = A->m;

A->data[0][1] = A->n;
A->data[0][2] = A->value;
for(i = 1;i <= A->value;i ++)
{


for(j = 0;j < 3; j ++)

scanf("%d",&A->data[i][j]);
}
return A;


}
void Output(matrix *A)
{ int i,j;


printf("************************************\n");
for(i = 0;i <= A->value;i ++)
{


for(j = 0;j < 3;j ++)
printf("%d ",A->data[i][j]);

printf("\n");
}
printf("************************************\n");

}
matrix *addmatrix(matrix *A,matrix *B,matrix *C)
{ int i = 1,j =1,k = 1;


C = (matrix*)malloc(sizeof(matrix));
while(i <= A->value && j <= B->value)


{
if(A->data[i][0] == B->data[j][0])
{



if(A->data[i][1] == B->data[j][1])

{
C->data[k][0] = A->data[i][0];
C->data[k][1] = A->data[i][1];
C->data[k][2] = A->data[i][2] + B->data[j][2];
if(C->data[k][2] != 0) k ++;
i ++;
j ++;

}
else if(A->data[i][1] < B->data[j][1])
{


C->data[k][0] = A->data[i][0];
C->data[k][1] = A->data[i][1];
C->data[k][2] = A->data[i][2];

k ++;

i ++;
}
else
{


C->data[k][0] = B->data[j][0];
C->data[k][1] = B->data[j][1];
C->data[k][2] = B->data[j][2];

k ++;
j ++;


}
}
else if(A->data[i][0] < B->data[j][0])
{

C->data[k][0] = A->data[i][0];
C->data[k][1] = A->data[i][1];
C->data[k][2] = A->data[i][2];

k ++;

i ++;
}
else
{

C->data[k][0] = B->data[j][0];
C->data[k][1] = B->data[j][1];
C->data[k][2] = B->data[j][2];


k ++;
j ++;
}
}
while(i <= A->value)


{
C->data[k][0] = A->data[i][0];
C->data[k][1] = A->data[i][1];
C->data[k][2] = A->data[i][2];


k ++;
i ++;
}
while(j <= B->value)


{
C->data[k][0] = B->data[j][0];
C->data[k][1] = B->data[j][1];
C->data[k][2] = B->data[j][2];


k ++;
j ++;
}


C->data[0][0] = (A->data[0][0]>=B->data[0][0])?A->data[0][0]:B->data[0][0];
C->data[0][1] = (A->data[0][1]>=B->data[0][1])?A->data[0][1]:B->data[0][1];

C->data[0][2] = k-1;
C->value = k-1;
return C;


}
int main()
{

matrix * A = NULL,*B = NULL,*C = NULL;
printf("提示:请按三元组格式输入矩阵内容。
\n");
printf("Input A matrix:\n");
A = Input(A);
printf("Input B matr

ix:\n");
B = Input(B);
C = addmatrix(A,B,C);
Output(C);
free(A);
free(B);



free(C);
return 0;
}

程序运行时按照三元组的格式输入矩阵信息,程序运行结果如下图所示:



4.16写出两个稀疏矩阵相乘的算法,计算:
Cpn = Apm .Bmn
其中,A、B和
C都采用三元组表示法存储。
【答】:


#include
#include
#define MAX 100
typedef struct{


int data[MAX][3];

int m,n,value;
}matrix;
matrix *Input(matrix *A)
{ int i,j;


A = (matrix*)malloc(sizeof(matrix));
scanf("%d%d%d",&A->m,&A->n,&A->value);
A->data[0][0] = A->m;


A->data[0][1] = A->n;
A->data[0][2] = A->value;
for(i = 1;i <= A->value;i ++)
{


for(j = 0;j < 3; j ++)

scanf("%d",&A->data[i][j]);
}
return A;


}
void Output(matrix *A)
{

int i,j;
printf("*******************************\n");
for(i = 0;i <= A->value;i ++)
{


for(j = 0;j < 3;j ++)
printf("%d ",A->data[i][j]);

printf("\n");
}
printf("*******************************\n");

}
/* 基于三元组存储结构的矩阵相乘算法
*/
matrix *MulMatrix(matrix *A,matrix *B,matrix *C)
{ int i ,j ,k ,r=1,p,q,s;


C = (matrix*)malloc(sizeof(matrix));
C->m=A->m;
C->n=B->n;
C->data[0][0]=C->m;
C->data[0][1]=C->n;
for (i=0;im;i++)


for (j=0;jn;j++)

{
s=0;
for (k=0;kn;k++)
//找
A[i][k];
{
p=1;
while (p<=A->value)


if (A->data[p][0]==i&&A->data[p][1]==k)
break;


else p++;

//找
B[k][j];
q=1;
while (q<=B->value)

if (B->data[q][0]==k&&B->data[q][1]==j)
break;
else q++;
if (p<=A->value && q<=B->value)

s=s+A->data[p][2]*B->data[q][2];
}
if (s!=0)
{ C->data[r][0]=i;

C->data[r][1]=j;
C->data[r][2]=s;
r++;

}

}
C->data[0][2]=r-1;
C->value=r-1;
return C;


}

int main()

{
matrix * A = NULL,*B = NULL,*C = NULL;
printf("提示:请按三元组格式输入矩阵内容。
\n");
printf("Input A matrix:\n");
A = Input(A);
printf("Input B matrix:\n");
B = Input(B);
C = MulMatrix(A,B,C);
Output(C);
free(A);
free(B);
free(C);
return 0;

}

程序运行时,要求按照三元组的格式输入矩阵信息。



相关文档