push(S,t[k]);
k=k+n%2;
while(!
stackempty(S))
{ch=pop(S);
if(ch==t[k])k++;
elsereturn0;
}
retuen1;
}
7.利用栈的基本操作,写一个将栈S中所有元素均出栈的算法voidClearstack(Seqstack*S),并说明S为何要作为指针参数?
【答案】算法如下:
voidClearstack(Seqstack*S)
{while(!
stackempty(S))
pop(S);
}
说明:
出栈操作为加工型操作,需要将操作后的结果带回主调程序段,所以S要作为指针参数。
8.利用栈的基本操作,写一个返回栈S中结点个数的算法intstacksize(SeqstackS),并说明S为何不用作为指针参数?
【答案】算法如下:
intstacksize(SeqstackS)
{
returnS.top+1;
}
说明:
统计结点个数操作为引用型操作,栈S的内容没有被修改,所以S不用作为指针参数。
由于C语言数组下标从0开始,故结点个数为S.top+1。
9.设计算法判断一个算术表达式的圆括号是否正确配对。
(提示:
凡遇‘(‘就进栈,遇‘)’就退掉栈顶的‘(‘,表达式扫描完毕,栈应为空)
intbracketsmatch(chara[])
{//设算术表达式以字符串形式存储在数组中
Seqstack*S;
Initstack(S);
intk=0;
while(a[k]!
=’\0’)
if(a[k]=='(')Push(S,'(');
elseif(a[k]==')')
if(Stackempty(S))return0;
elsePop(S);
if(Stackempty(S))return1;
elsereturn0;
}
10.一个双向栈S是在同一向量空间里实现的两个栈,它们的栈底分别设在向量空间的两端。
试为此双向栈设计初始化Initstack(S)、入栈push(S,x,i)和出栈pop(i)算法,其中,i为0或1用于指示栈号。
【答案】
#definmaxsize100
typedefstructnode{
datatypedata[maxsize];
inttop1,top2;
}Seqstack;
(1)双向栈的初始化
viodInitstack(Seqstack*S)
{
S->top1=-1;S->top2=maxsize;
}
(2)双向栈入栈算法
viodpush(Seqstack*S,datatypex,inti)
{if(S->top1+1==S->top2)
erroe(overflow);
else
if(i==0)
{S->top1++;
S->data[S->top1]=x;}
else
{S->top2--;
S->data[S->top2]=x;}
}
(3)双向栈出栈算法
datatypepop(Seqstack*S,inti)
{if(i==0)
if(S->top1==-1)
error(downflow);
else
{returnS->data[S->top1]}
else
if(S->top2==maxsize)
error(downflow);
else
returnS->data[S->top2];
}
11.Ackerman函数的定义如下:
n+1当m=0时
AKM(m,n)=AKM(m-1,1)当m≠0,n=0时
AKM(m-1,AKM(m,n-1)) 当m≠0,n≠0时
请写出递归算法。
【答案】算法如下:
intakm(intn,intm)
{if(m==0)
returnn+1;
elseif(n==0&&m!
=0)
returnakm(m-1,1);
else
returnakm(m-1,akm(m,n-1));
}
12.用第二种方法,既少用一个元素空间的方法来区别循环队列的空和满,试为其设计置队空、判断队空、判断队满、出队、入队、取队头元素等六个基本操作的算法。
【答案】算法如下:
#definmaxsize100
typedefstructnode{
datatypedata[maxsize];
intfront,rear;
}Seqqueue;
(1)置队空操作
voidInitqueue(Seqqueue*Q)
{Q->front=0;
Q->rear=0;
}
(2)判断队空操作
intQueueempty(SeqqueueQ)
{
returnO.front==Q.rear;
}
(3)判断队满操作
intQueuefull(SeqqueueQ)
{
returnO.front==(Q.rear+1)%maxsize;
}
(4)出队操作
datatypedelquequ(Seqqueue*Q)
{datatypetemp;
if(O->front==Q->rear)
error("downflow");
temp=Q->data[Q->front];
Q->front=(Q->front+1)%maxsize;
returntemp;
}
(5)入队操作
voidenqueue(Seqqueue*Q,datatypex)
{if(Q->front==(Q->rear+1)%maxsize)
error("overflow");
Q->data[Q->rear]=x;
Q->rear=(Q->rear+1)%maxsize;
}
(6)取队头操作
datatypedelquequ(Seqqueue*Q)
{datatypetemp;
if(O->front==Q->rear)
error("downflow");
returnQ->data[Q->front];
}
13.假设以带头结点的循环链表表示队列,并且只是一个指针指向队尾元素结点,试编写相应的置队空、判断队空、出队和入队等算法。
typedefstructnode{
datatypedata;
structnode*next;
}Linknode;
typedefstruct{
Linknode*rear;
}Linkqueue;
(1)置队空操作
voidInitqueue(Linkqueue*Q)
{Q->rear=(linknode*)malloc(sizeof(Linknode))
Q->rear->next=Q->reqr;
}
(2)判断队空操作
intQueueempty(SeqqueueQ)
{
returnQ.rear->next=Q.reqr;
}
(3)出队操作
datatypedelquequ(Linkqueue*Q)
{datatypetemp;
Linknode*p;
if(O->rear->next==Q->rear)
error("downflow");
p=Q->rear->next->next;
temp=p->data;
Q->rear->next->next=p->next;
if(p==Q->rear)Q->rear=Q->rear->next;
free(p);
returntemp;
}
(4)入队操作
voidenqueue(Linkqueue*Q,datatypex)
{Linknode*p;
p=(Linknode*)malloc(sizeof(Linknode));
p->data=x;
p->next=Q->rear->next;
Q->rear->next=p;
Q->rear=p;
}
14.对于循环向量中的循环队列,写出求队列长度的公式。
【答案】循环队列求队列长度的公式为:
(Q.rear-Q.front+maxsize)%maxsize
15.假设循环队列中只设rear和quelen来分别指示队尾元素的位置和队中元素的个数,试给出循环队列的队满条件,并写出相应的入队和出队算法,要求出队时需返回队头元素。
【答案】
(1)队满条件:
Q.quelen==maxsize
(2)入队算法:
voidenqueue(cirqueue*Q,datatypex)
{if(O->quelen==maxsize)
error("overflow");
Q->rear=(Q->reae+1)%maxsize;
Q->data[Q->rear]=x;
}
(3)出队算法:
datatypedelqueue(cirqueue*Q)
{datatypex;
if(O->quelen==0)
error("downflow");
x=Q->data[(Q->reae+maxsize-Q->quelen+1)%maxsize];
Q->quelen--;
returnx;
}
串
一、选择题
1.下所述中正确的是()〖2001〗
A.串是一种特殊的线性表B. 串的长度必须大于零
C.串中元素只能是字母 D.空串就是空白串
〖答案〗A
2.若目标串的长度为n,模式串的长度为[n/3],则执行模式匹配算法时,在最坏情况下的时间复杂度是( )〖2001〗
A.O(n/3) B.O(n) C.O(n2) D.O(n3)
〖分析〗最坏情况下模式匹配的时间复杂度为O((n-[n/3]+1)*[n/3]),由于n和[n/3]是同阶的,所以,时间复杂度可写为O(n2)。
〖答案〗C
3.设有两个串T和P,求P在T中首次出现的位置的串运算称作( )〖2003〗
A.联接 B.求子串 C.字符定位 D.子串定位
〖分析〗该题考核点是串的基本操作。
〖答案〗D
4.为查找某一特定单词在文本中出现的位置,可应用的串运算是( )〖2002〗
A.插入 B.删除 C.串联接 D.子串定位
〖答案〗D
5.已知函数Sub(s,i,j)的功能是返回串s中从第i个字符起长度为j的子串,函数Scopy(s,t)的功能为复制串t到s。
若字符串S="SCIENCESTUDY",则调用函数Scopy(P,Sub(S,1,7))后得到( )〖2002〗
A.P="SCIENCE" B.P="STUDY"
C.S="SCIENCE" D.S="STUDY"
〖分析〗该题考核点是串的基本操作,函数Scopy(P,Sub(S,1,7))将串中子串″SCIENCE″复制到P中,而串S值未变。
正确答案为A。
〖答案〗A
二、填空题
6.在串S="structure"中,以t为首字符的子串有 个。
〖2001〗
〖分析〗该题考核点是子串的概念。
其中存在两个长度为1的子串。
〖答案〗12
7.串S="Iamaworker"的长度是________。
〖2002〗
〖分析〗该题考核点是串长度的概念。
〖答案〗13
8.设S1="good",S2=" ",S3="book",则S1,S2和S3依次联接后的结果是____________。
〖2003〗
〖分析〗该题考核点是串的连接操作及空白串的概念。
〖答案〗"good book"
三、算法阅读题
9.下列算法的功能是比较两个链串的大小,其返回值为:
-1s1comstr(s1,s2)=0s1=s2
1s1>s2
请在空白处填入适当的内容。
〖2001〗
intcomstr(linkstrings1,linkstrings2)
{//s1和s2为两个链串的头指针
while(s1&&s2){
if(s1->datadata)return–1;
if(s1->data>s2->data)return1;
①
②
}
if(③)return–1;
if(④)return1;
⑤;
}
〖分析〗该题考核点是串的比较操作。
While型循环通过指针s1、s2将两个串中字符逐一比较,若发现不等字符,则不等字符的大小就是两个串的大小;若所比较字符均相等,直到有串被扫描完为止,退出循环。
然后判断,若某个串未被扫描完,则其值大,若两个串同时被扫描完,则两个串相等。
〖答案〗① s1=s1->next;②s2=s2->next;③s2(或s2!
=NULL)④s1(或s1!
=NULL)⑤return0
同步练习题
一、选择题
1.下列有关字符串的描述,正确的是()
A.字符串是0个或多个字符构成的有限序列;
B.字符串是0个或多个字母不同的有限序列;
C.字符串中最少要有一个子符;
D.字符串中不能有空格字符。
2.字符串S="string"中,包含的子串的个数是()
A.20B.21C.22D.23
3.目标串为T="thisisastring",模式串P="string",进行模式匹配,有效位移是()(起始位置为0)。
A.9B.10C.11D.12
4.已知串S="string",T="this",执行运算strlen(strcopy(S,T))的结果是()
A.4B.6C.10D.2
5.目标串为T="thisisastring",模式串P="string",进行模式匹配,所有的无效位移数是()
A.6B.10C.16D.11
6.下列命题正确的是()
A.空串就是空白串;B.空串不是串;
C.空串是长度为0的字符串D.串相等指的是长度相等
7.若字符串采用链式存储,每个字符占用一个字节,每个指针在占用四个字节,则该字符串的存储密度为()
A.50%B.25%C.75%D.20%
8.当目标串的长度为n,模式串的长度为m时,朴素的模式匹配算法最坏情况下字符的比较次数()
A.nB.n*mC.(n-m+1)*mD.m
9.当目,模式串的长度为m时,朴素的模式匹配算法最好情况下字符的比较次数()
A.nB.mC.n+mDn-m
10.字符串是一种特殊的线性表,它与一般线性表的区别是()
A.字符串是一种线性结构;
B.字符串可以进行复制操作;
C.字符串由字符构成并且通常作为整体参与操作;
D.字符串可以顺序存储也可以链式存储。
二、填空题
1.空串的长度为,空格串(空白串)的长度为。
2.子串的定位运算又称为,通常把主串又称为子串又称为。
3.成功匹配的起始位置称为,匹配失败的起始位置称为。
4.设目标串为T="abccdadeef",模式串P="ade",则第趟匹配成功。
5.已知串T="abccdadeef",P="abccyde",函数strcmp(T,P)的运算结果是。
6.串朴素的模式匹配算法在顺序串和链串上运行,时间复杂度。
7.已知串T="abccdadeef",T中包含以b打头的子串有个。
8.通常在程序设计中,串分为和。
9.按存储结构通常分为和。
10.设s1="GOOD",s2=" ",s3="BYE!
",则s1,s2,和s3连接后的结果是。
三.阅读程序题
1.指出程序功能
intstringcmp(HstringS,HstringT)
{inti=0,tag=1;
if(S.length!
=T.length)tag=0;
else
while(iif(S.ch[i]==T.ch[i])i++;
elsetag=0;
returntag;
}
2.阅读程序
intstringpatindex(HstringS,HstringT)
{inti,j,k;
for(i=0;i{for(j=i,k=0;kif(S.ch[j]!
=T.ch[k]&&|T[k]!
='?
')
break;
if(k>=T.length)returni;
}
return–1;
}
(1)指出程序功能;
(2)设S中存储"thereareastring",T中存储"?
?
r"函数的返回值是什么?
3.阅读程序指出程序功能
voidrestring(HstringS)
{char*p,*q,c;
p=S.ch;q=S.ch+S.length-1;
while(p{c=*p;*p=*q;*q=c;
p++;q--;
}
}
四、程序设计题
1.编写算法实现两个串的连接。
2.设计算法删除主串中所有指定子串
3.编写算法判断串是否为回文
同步练习题答案
一、选择题
1.A2.C 3.C 4.A 5.B 6.C 7.D 8.C 9.B 10.C
二、填空题
1.0,包含空格的的数;2.模式匹配,目标串,模式串;3.有效位移,无效位移;
4.6; 5.<0; 6.O(m+n);7.9;
8.串常量,串变量; 9.顺序串,链串; 10.GOODBYE!
三.阅读程序题
1.【答案】判断两个串是否相等,若相等返回1,否则返回0。
2.【答案】
(1)带通配符?
的子串定位函数;
(2)返回值为1。
3.【答案】将一个串逆置。
四、程序设计题
2.实现两个串的连接算法:
voidstringcat(HstringS,HstringT)
{char*p,*q;
p=S.ch+S.length;
q=t.ch;
while(p