数据机构第四章——java语言描述 第4章 串与数组 习题参考答案..

合集下载

数据结构课后习题答案第四章

数据结构课后习题答案第四章

第四章一、简述下列每对术语的区别:空串和空白串;串常量和串变量;主串和子串;静态分配的顺序串和动态分配的顺序串;目标串和模式串;有效位移和无效位移。

答:●空串是指不包含任何字符的串,它的长度为零。

空白串是指包含一个或多个空格的串,空格也是字符。

●串常量是指在程序中只可引用但不可改变其值的串。

串变量是可以在运行中改变其值的。

●主串和子串是相对的,一个串中任意个连续字符组成的串就是这个串的子串,而包含子串的串就称为主串。

●静态分配的顺序串是指串的存储空间是确定的,即串值空间的大小是静态的,在编译时刻就被确定。

动态分配的顺序串是在编译时不分配串值空间,在运行过程中用malloc和free等函数根据需要动态地分配和释放字符数组的空间(这个空间长度由分配时确定,也是顺序存储空间)。

●目标串和模式串:在串匹配运算过程中,将主串称为目标串,而将需要匹配的子串称为模式串,两者是相对的。

●有效位移和无效位移:在串定位运算中,模式串从目标的首位开始向右位移,每一次合法位移后如果模式串与目标中相应的字符相同,则这次位移就是有效位移(也就是从此位置开始的匹配成功),反之,若有不相同的字符存在,则此次位移就是无效位移(也就是从此位置开始的匹配失败)。

二、假设有如下的串说明:char s1[30]="Stocktom,CA", s2[30]="March 5 1999", s3[30], *p;(1)在执行如下的每个语句后p的值是什么?p=stchr(s1,'t'); p=strchr(s2,'9'); p=strchr(s2,'6');(2)在执行下列语句后,s3的值是什么?strcpy(s3,s1); strcat(s3,","); strcat(s3,s2);(3)调用函数strcmp(s1,s2)的返回值是什么?(4)调用函数strcmp(&s1[5],"ton")的返回值是什么?(5)调用函数stlen(strcat(s1,s2))的返回值是什么?解:(1) stchr(*s,c)函数的功能是查找字符c在串s中的位置,若找到,则返回该位置,否则返回NULL。

严蔚敏数据结构详细答案

严蔚敏数据结构详细答案

严蔚敏 数据结构C 语言版答案详解第1章 绪论1.1 简述下列术语:数据,数据元素、数据对象、数据结构、存储结构、数据类型和抽象数据类型。

解:数据是对客观事物的符号表示。

在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。

数据元素是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。

数据对象是性质相同的数据元素的集合,是数据的一个子集。

数据结构是相互之间存在一种或多种特定关系的数据元素的集合。

存储结构是数据结构在计算机中的表示。

数据类型是一个值的集合和定义在这个值集上的一组操作的总称。

抽象数据类型是指一个数学模型以及定义在该模型上的一组操作。

是对一般数据类型的扩展。

1.2 试描述数据结构和抽象数据类型的概念与程序设计语言中数据类型概念的区别。

解:抽象数据类型包含一般数据类型的概念,但含义比一般数据类型更广、更抽象。

一般数据类型由具体语言系统内部定义,直接提供给编程者定义用户数据,因此称它们为预定义数据类型。

抽象数据类型通常由编程者定义,包括定义它所使用的数据和在这些数据上所进行的操作。

在定义抽象数据类型中的数据部分和操作部分时,要求只定义到数据的逻辑结构和操作说明,不考虑数据的存储结构和操作的具体实现,这样抽象层次更高,更能为其他用户提供良好的使用接口。

1.3 设有数据结构(D,R),其中{}4,3,2,1d d d d D =,{}r R =,()()(){}4,3,3,2,2,1d d d d d d r =试按图论中图的画法惯例画出其逻辑结构图。

解:1.4 试仿照三元组的抽象数据类型分别写出抽象数据类型复数和有理数的定义(有理数是其分子、分母均为自然数且分母不为零的分数)。

解:ADT Complex{ 数据对象:D={r,i|r,i 为实数} 数据关系:R={<r,i>} 基本操作: InitComplex(&C,re,im)操作结果:构造一个复数C ,其实部和虚部分别为re 和im DestroyCmoplex(&C)操作结果:销毁复数C Get(C,k,&e)操作结果:用e 返回复数C 的第k 元的值Put(&C,k,e)操作结果:改变复数C的第k元的值为eIsAscending(C)操作结果:如果复数C的两个元素按升序排列,则返回1,否则返回0 IsDescending(C)操作结果:如果复数C的两个元素按降序排列,则返回1,否则返回0 Max(C,&e)操作结果:用e返回复数C的两个元素中值较大的一个Min(C,&e)操作结果:用e返回复数C的两个元素中值较小的一个}ADT ComplexADT RationalNumber{数据对象:D={s,m|s,m为自然数,且m不为0}数据关系:R={<s,m>}基本操作:InitRationalNumber(&R,s,m)操作结果:构造一个有理数R,其分子和分母分别为s和mDestroyRationalNumber(&R)操作结果:销毁有理数RGet(R,k,&e)操作结果:用e返回有理数R的第k元的值Put(&R,k,e)操作结果:改变有理数R的第k元的值为eIsAscending(R)操作结果:若有理数R的两个元素按升序排列,则返回1,否则返回0 IsDescending(R)操作结果:若有理数R的两个元素按降序排列,则返回1,否则返回0 Max(R,&e)操作结果:用e返回有理数R的两个元素中值较大的一个Min(R,&e)操作结果:用e返回有理数R的两个元素中值较小的一个}ADT RationalNumber1.5 试画出与下列程序段等价的框图。

第四章 数据结构串课后答案

第四章 数据结构串课后答案

第四章串4.10void String_Reverse(Stringtype s,Stringtype &r)//求s的逆串r{StrAssign(r,''); //初始化r为空串for(i=Strlen(s);i;i--){StrAssign(c,SubString(s,i,1));StrAssign(r,Concat(r,c)); //把s的字符从后往前添加到r中}}//String_Reverse4.11void String_Subtract(Stringtype s,Stringtype t,Stringtype &r)//求所有包含在串s中而t中没有的字符构成的新串r{StrAssign(r,'');for(i=1;i<=Strlen(s);i++){StrAssign(c,SubString(s,i,1));for(j=1;j<i&&StrCompare(c,SubString(s,j,1));j++); //判断s的当前字符c是否第一次出现if(i==j){for(k=1;k<=Strlen(t)&&StrCompare(c,SubString(t,k,1));k++); //判断当前字符是否包含在t中if(k>Strlen(t)) StrAssign(r,Concat(r,c));}}//for}//String_Subtract4.12int Replace(Stringtype &S,Stringtype T,Stringtype V);//将串S中所有子串T替换为V,并返回置换次数{for(n=0,i=1;i<=Strlen(S)-Strlen(T)+1;i++) //注意i的取值范围if(!StrCompare(SubString(S,i,Strlen(T)),T)) //找到了与T匹配的子串{ //分别把T的前面和后面部分保存为head和tailStrAssign(head,SubString(S,1,i-1));StrAssign(tail,SubString(S,i+Strlen(T),Strlen(S)-i-Strlen(T)+1));StrAssign(S,Concat(head,V));StrAssign(S,Concat(S,tail)); //把head,V,tail连接为新串i+=Strlen(V); //当前指针跳到插入串以后n++;}//ifreturn n;}//Replace分析:i+=Strlen(V);这一句是必需的,也是容易忽略的.如省掉这一句,则在某些情况下,会引起不希望的后果,虽然在大多数情况下没有影响.请思考:设S='place',T='ace', V='face',则省掉i+=Strlen(V);运行时会出现什么结果?4.13int Delete_SubString(Stringtype &s,Stringtype t)//从串s中删除所有与t相同的子串,并返回删除次数{for(n=0,i=1;i<=Strlen(s)-Strlen(t)+1;i++)if(!StrCompare(SubString(s,i,Strlen(t)),t)){StrAssign(head,SubString(S,1,i-1));StrAssign(tail,SubString(S,i+Strlen(t),Strlen(s)-i-Strlen(t)+1));StrAssign(S,Concat(head,tail)); //把head,tail连接为新串n++;}//ifreturn n,}//Delete_SubString4.14Status NiBoLan_to_BoLan(Stringtype str,Stringtype &new)//把前缀表达式str转换为后缀式new{Initstack(s); //s的元素为Stringtype类型for(i=1;i<=Strlen(str);i++){r=SubString(str,i,1);if(r为字母) push(s,r);else{if(StackEmpty(s)) return ERROR;pop(s,a);if(StackEmpty(s)) return ERROR;pop(s,b);StrAssign(t,Concat(r,b));StrAssign(c,Concat(t,a)); //把算符r,子前缀表达式a,b连接为新子前缀表达式cpush(s,c);}}//forpop(s,new);if(!StackEmpty(s)) return ERROR;return OK;}//NiBoLan_to_BoLan分析:基本思想见书后注释3.23.请读者用此程序取代作者早些时候对3.23题给出的程序.4.15void StrAssign(Stringtype &T,char chars&#;)//用字符数组chars给串T赋值,Stringtype的定义见课本{for(i=0,T[0]=0;chars[i];T[0]++,i++) T[i+1]=chars[i];}//StrAssign4.16char StrCompare(Stringtype s,Stringtype t)//串的比较,s>t时返回正数,s=t时返回0,s<t时返回负数{for(i=1;i<=s[0]&&i<=t[0]&&s[i]==t[i];i++);if(i>s[0]&&i>t[0]) return 0;else if(i>s[0]) return -t[i];else if(i>t[0]) return s[i];else return s[i]-t[i];}//StrCompare4.17int String_Replace(Stringtype &S,Stringtype T,Stringtype V);//将串S中所有子串T 替换为V,并返回置换次数{for(n=0,i=1;i<=S[0]-T[0]+1;i++){for(j=i,k=1;T[k]&&S[j]==T[k];j++,k++);if(k>T[0]) //找到了与T匹配的子串:分三种情况处理{if(T[0]==V[0])for(l=1;l<=T[0];l++) //新子串长度与原子串相同时:直接替换S[i+l-1]=V[l];else if(T[0]<V[0]) //新子串长度大于原子串时:先将后部右移{for(l=S[0];l>=i+T[0];l--)S[l+V[0]-T[0]]=S[l];for(l=1;l<=V[0];l++)S[i+l-1]=V[l];}else //新子串长度小于原子串时:先将后部左移{for(l=i+V[0];l<=S[0]+V[0]-T[0];l++)S[l]=S[l-V[0]+T[0]];for(l=1;l<=V[0];l++)S[i+l-1]=V[l];}S[0]=S[0]-T[0]+V[0];i+=V[0];n++;}//if}//forreturn n;}//String_Replace4.18typedef struct {char ch;int num;} mytype;void StrAnalyze(Stringtype S)//统计串S中字符的种类和个数{mytype T[MAXSIZE]; //用结构数组T存储统计结果for(i=1;i<=S[0];i++){c=S[i];j=0;while(T[j].ch&&T[j].ch!=c) j++; //查找当前字符c是否已记录过if(T[j].ch) T[j].num++;else T[j]={c,1};}//forfor(j=0;T[j].ch;j++)printf("%c: %d\n",T[j].ch,T[j].num);}//StrAnalyze4.19void Subtract_String(Stringtype s,Stringtype t,Stringtype &r)//求所有包含在串s中而t中没有的字符构成的新串r{r[0]=0;for(i=1;i<=s[0];i++){c=s[i];for(j=1;j<i&&s[j]!=c;j++); //判断s的当前字符c是否第一次出现if(i==j){for(k=1;k<=t[0]&&t[k]!=c;k++); //判断当前字符是否包含在t中if(k>t[0]) r[++r[0]]=c;}}//for}//Subtract_String4.20int SubString_Delete(Stringtype &s,Stringtype t)//从串s中删除所有与t相同的子串,并返回删除次数{for(n=0,i=1;i<=s[0]-t[0]+1;i++){for(j=1;j<=t[0]&&s[i+j-1]==t[i];j++);if(j>m) //找到了与t匹配的子串{for(k=i;k<=s[0]-t[0];k++) s[k]=s[k+t[0]]; //左移删除s[0]-=t[0];n++;}}//forreturn n;}//Delete_SubString4.21typedef struct{char ch;LStrNode *next;} LStrNode,*LString; //链串结构void StringAssign(LString &s,LString t)//把串t赋值给串s{s=malloc(sizeof(LStrNode));for(q=s,p=t->next;p;p=p->next){r=(LStrNode*)malloc(sizeof(LStrNode));r->ch=p->ch;q->next=r;q=r;}q->next=NULL;}//StringAssignvoid StringCopy(LString &s,LString t)//把串t复制为串s.与前一个程序的区别在于,串s业已存在.{for(p=s->next,q=t->next;p&&q;p=p->next,q=q->next){p->ch=q->ch;pre=p;}while(q){p=(LStrNode*)malloc(sizeof(LStrNode));p->ch=q->ch;pre->next=p;pre=p;}p->next=NULL;}//StringCopychar StringCompare(LString s,LString t)//串的比较,s>t时返回正数,s=t时返回0,s<t 时返回负数{for(p=s->next,q=t->next;p&&q&&p->ch==q->ch;p=p->next,q=q->next);if(!p&&!q) return 0;else if(!p) return -(q->ch);else if(!q) return p->ch;else return p->ch-q->ch;}//StringCompareint StringLen(LString s)//求串s的长度(元素个数){for(i=0,p=s->next;p;p=p->next,i++);return i;}//StringLenLString * Concat(LString s,LString t)//连接串s和串t形成新串,并返回指针{p=malloc(sizeof(LStrNode));for(q=p,r=s->next;r;r=r->next){q->next=(LStrNode*)malloc(sizeof(LStrNode));q=q->next;q->ch=r->ch;}//for //复制串sfor(r=t->next;r;r=r->next)q->next=(LStrNode*)malloc(sizeof(LStrNode));q=q->next;q->ch=r->ch;}//for //复制串tq->next=NULL;return p;}//ConcatLString * Sub_String(LString s,int start,int len)//返回一个串,其值等于串s从start 位置起长为len的子串{p=malloc(sizeof(LStrNode));q=p;for(r=s;start;start--,r=r->next); //找到start所对应的结点指针rfor(i=1;i<=len;i++,r=r->next){q->next=(LStrNode*)malloc(sizeof(LStrNode));q=q->next;q->ch=r->ch;} //复制串tq->next=NULL;return p;}//Sub_String4.22void LString_Concat(LString &t,LString &s,char c)//用块链存储结构,把串s插入到串t的字符c之后{p=t.head;while(p&&!(i=Find_Char(p,c))) p=p->next; //查找字符cif(!p) //没找到{t.tail->next=s.head;t.tail=s.tail; //把s连接在t的后面}else{q=p->next;r=(Chunk*)malloc(sizeof(Chunk)); //将包含字符c的节点p分裂为两个for(j=0;j<i;j++) r->ch[j]='#'; //原结点p包含c及其以前的部分for(j=i;j<CHUNKSIZE;j++) //新结点r包含c以后的部分{r->ch[j]=p->ch[j];p->ch[j]='#'; //p的后半部分和r的前半部分的字符改为无效字符'#'p->next=s.head;s.tail->next=r;r->next=q; //把串s插入到结点p和r之间}//elset.curlen+=s.curlen; //修改串长s.curlen=0;}//LString_Concatint Find_Char(Chunk *p,char c)//在某个块中查找字符c,如找到则返回位置是第几个字符,如没找到则返回0{for(i=0;i<CHUNKSIZE&&p->ch[i]!=c;i++);if(i==CHUNKSIZE) return 0;else return i+1;}//Find_Char4.23int LString_Palindrome(LString L)//判断以块链结构存储的串L是否为回文序列,是则返回1,否则返回0{InitStack(S);p=S.head;i=0;k=1; //i指示元素在块中的下标,k指示元素在整个序列中的序号(从1开始)for(k=1;k<=S.curlen;k++){if(k<=S.curlen/2) Push(S,p->ch[i]); //将前半段的字符入串else if(k>(S.curlen+1)/2){Pop(S,c); //将后半段的字符与栈中的元素相匹配if(p->ch[i]!=c) return 0; //失配}if(++i==CHUNKSIZE) //转到下一个元素,当为块中最后一个元素时,转到下一块{p=p->next;i=0;}}//forreturn 1; //成功匹配}//LString_Palindrome4.24void HString_Concat(HString s1,HString s2,HString &t)//将堆结构表示的串s1和s2连接为新串t{if(t.ch) free(t.ch);t.ch=malloc((s1.length+s2.length)*sizeof(char));for(i=1;i<=s1.length;i++) t.ch[i-1]=s1.ch[i-1];for(j=1;j<=s2.length;j++,i++) t.ch[i-1]=s2.ch[j-1];t.length=s1.length+s2.length;}//HString_Concat4.25int HString_Replace(HString &S,HString T,HString V)//堆结构串上的置换操作,返回置换次数{for(n=0,i=0;i<=S.length-T.length;i++){for(j=i,k=0;k<T.length&&S.ch[j]==T.ch[k];j++,k++);if(k==T.length) //找到了与T匹配的子串:分三种情况处理{if(T.length==V.length)for(l=1;l<=T.length;l++) //新子串长度与原子串相同时:直接替换S.ch[i+l-1]=V.ch[l-1];else if(T.length<V.length) //新子串长度大于原子串时:先将后部右移{for(l=S.length-1;l>=i+T.length;l--)S.ch[l+V.length-T.length]=S.ch[l];for(l=0;l<V.length;l++)S[i+l]=V[l];}else //新子串长度小于原子串时:先将后部左移{for(l=i+V.length;l<S.length+V.length-T.length;l++)S.ch[l]=S.ch[l-V.length+T.length];for(l=0;l<V.length;l++)S[i+l]=V[l];}S.length+=V.length-T.length;i+=V.length;n++;}//if}//forreturn n;}//HString_Replace4.26Status HString_Insert(HString &S,int pos,HString T)//把T插入堆结构表示的串S的第pos个字符之前{if(pos<1) return ERROR;if(pos>S.length) pos=S.length+1;//当插入位置大于串长时,看作添加在串尾S.ch=realloc(S.ch,(S.length+T.length)*sizeof(char));for(i=S.length-1;i>=pos-1;i--)S.ch[i+T.length]=S.ch[i]; //后移为插入字符串让出位置for(i=0;i<T.length;i++)S.ch[pos+i-1]=T.ch[pos]; //插入串TS.length+=T.length;return OK;}//HString_Insert4.27int Index_New(Stringtype s,Stringtype t)//改进的定位算法{i=1;j=1;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]])){ //当j==1即匹配模式串的第一个字符时,需同时匹配其最后一个i=i+j-2;j=1;}else{i++;j++;}}//whileif(j>t[0]) return i-t[0];}//Index_New4.28void LGet_next(LString &T)//链串上的get_next算法{p=T->succ;p->next=T;q=T;while(p->succ){if(q==T||p->data==q->data){p=p->succ;q=q->succ;p->next=q;else q=q->next;}//while}//LGet_next4.29LStrNode * LIndex_KMP(LString S,LString T,LStrNode *pos)//链串上的KMP匹配算法,返回值为匹配的子串首指针{p=pos;q=T->succ;while(p&&q){if(q==T||p->chdata==q->chdata){p=p->succ;q=q->succ;}else q=q->next;}//whileif(!q){for(i=1;i<=Strlen(T);i++)p=p->next;return p;} //发现匹配后,要往回找子串的头return NULL;}//LIndex_KMP4.30void Get_LRepSub(Stringtype S)//求S的最长重复子串的位置和长度{for(maxlen=0,i=1;i<S[0];i++)//串S2向右移i格{for(k=0,j=1;j<=S[0]-i;j++)//j为串S2的当前指针,此时串S1的当前指针为i+j,两指针同步移动{if(S[j]==S[j+i]) k++; //用k记录连续相同的字符数else k=0; //失配时k归零if(k>maxlen) //发现了比以前发现的更长的重复子串{lrs1=j-k+1;lrs2=mrs1+i;maxlen=k; //作记录}}//forif(maxlen){printf("Longest Repeating Substring length:%d\n",maxlen);printf("Position1:%d Position 2:%d\n",lrs1,lrs2);}else printf("No Repeating Substring found!\n");}//Get_LRepSub分析:i代表"错位值".本算法的思想是,依次把串S的一个副本S2向右错位平移1格,2格,3格,...与自身S1相匹配,如果存在最长重复子串,则必然能在此过程中被发现.用变量lrs1,lrs2,maxlen来记录已发现的最长重复子串第一次出现位置,第二次出现位置和长度.题目中未说明"重复子串"是否允许有重叠部分,本算法假定允许.如不允许,只需在第二个for语句的循环条件中加上k<=i即可.本算法时间复杂度为O(Strlen(S)^2).4.31void Get_LPubSub(Stringtype S,Stringtype T)//求串S和串T的最长公共子串位置和长度{if(S[0]>=T[0]){StrAssign(A,S);StrAssign(B,T);}else{StrAssign(A,T);StrAssign(B,S);} //为简化设计,令S和T中较长的那个为A,较短的那个为Bfor(maxlen=0,i=1-B[0];i<A[0];i++){if(i<0) //i为B相对于A的错位值,向左为负,左端对齐为0,向右为正{jmin=1;jmax=i+B[0];}//B有一部分在A左端的左边else if(i>A[0]-B[0]){jmin=i;jmax=A[0];}//B有一部分在A右端的右边else{jmin=i;jmax=i+B[0];}//B在A左右两端之间.//以上是根据A和B不同的相对位置确定A上需要匹配的区间(与B重合的区间)的端点:jmin,jmax.for(k=0,j=jmin;j<=jmax;j++)if(A[j]==B[j-i]) k++;else k=0;if(k>maxlen){lps1=j-k+1;lps2=j-i-k+1;maxlen=k;}}//for}//forif(maxlen){if(S[0]>=T[0]){lpsS=lps1;lpsT=lps2;}else{lpsS=lps2;lpsT=lps1;} //将A,B上的位置映射回S,T上的位置printf("Longest Public Substring length:%d\n",maxlen);printf("Position in S:%d Position in T:%d\n",lpsS,lpsT);}//ifelse printf("No Repeating Substring found!\n");}//Get_LPubSub分析:本题基本思路与上题同.唯一的区别是,由于A,B互不相同,因此B不仅要向右错位,而且还要向左错位,以保证不漏掉一些情况.当B相对于A的位置不同时,需要匹配的区间的计算公式也各不相同,请读者自己画图以帮助理解.本算法的时间复杂度是o(strlrn(s)*strlen(t))。

Java新教材第四章面试题

Java新教材第四章面试题

第4章数组和字符串操作 (63)4.1 数组 (63)4.1.1 为什么使用数组 (63)4.1.2 数组的基本概念 (64)●什么是数组?答案:数组是编程语言中非常常见的一种数据结构,它用来存储一组相同数据类型数据。

4.1.3 一维数组的创建和使用 (64)●下面哪一项是正确的定义一维数组的方式?答案:两种方式都正确。

4.1.4 一维数组的应用 (70)4.1.5 多维数组 (76)●什么是多维数组?答案:Java中支持多维数组,也就是“数组的数组”。

多维数组的声明是通过每一维一组方括号的方式来实现的。

●如何把一段逗号分割的字符串转换成一个数组?答案:如果不查jdk api,我很难写出来!我可以说说我的思路:用正则表达式,代码大概为:String [] result = orgStr.split(“,”);用StingTokenizer ,代码为:StringTokenizer tokener = StringTokenizer(orgStr,”,”);String [] result = new String[tokener .countTokens()];Int i=0;while(tokener.hasNext(){result[i++]=toker.nextToken();}●数组有没有length()这个方法?答案:数组没有length()这个方法,有length的属性。

String有有length()这个方法。

4.2 String字符串 (77)●请问数组和String有没有length()这个方法或length的属性。

·VI · 答案:数组没有length()这个方法,但有length 的属性。

String 有length()这个方法。

● 什么是字符串?答案:字符串是一系列字符组成的序列。

4.2.2 如何使用String 字符串....................................................................................77 ● String 字符串对象建立后,还能修改吗,为什么?答案:不能,因为String 类是字符串常量类,该类对象建立后不能修改。

数据结构第四章串习题及答案

数据结构第四章串习题及答案

习题四串一、单项选择题‎1.下面关于串‎的的叙述中‎,哪一个是不‎正确的?()A.串是字符的‎有限序列 B.空串是由空‎格构成的串‎C.模式匹配是‎串的一种重‎要运算 D.串既可以采‎用顺序存储‎,也可以采用‎链式存储2.串是一种特‎殊的线性表‎,其特殊性体‎现在()。

A.可以顺序存‎储 B.数据元素是‎一个字符C.可以链接存‎储 D.数据元素可‎以是多个字‎符3.串的长度是‎指()A.串中所含不‎同字母的个‎数 B.串中所含字‎符的个数C.串中所含不‎同字符的个‎数 D.串中所含非‎空格字符的‎个数4.设有两个串‎p和q,其中q是p‎的子串,求q在p中‎首次出现的‎位置的算法‎称为()A.求子串 B.联接 C.匹配 D.求串长5.若串S=“softw‎a re”,其子串的个‎数是()。

A.8 B.37 C.36 D.9二、填空题1.含零个字符‎的串称为_‎_____‎串。

任何串中所‎含____‎__的个数‎称为该串的‎长度。

2.空格串是指‎__ __,其长度等于‎__ __。

3.当且仅当两‎个串的__‎____相‎等并且各个‎对应位置上‎的字符都_‎_____‎时,这两个串相‎等。

一个串中任‎意个连续字‎符组成的序‎列称为该串‎的____‎__串,该串称为它‎所有子串的‎_____‎_串。

4.INDEX‎(‘DATAS‎T RUCT‎U RE’,‘STR’)=_____‎___。

5.模式串P=‘abaab‎c ac’的next‎函数值序列‎为____‎____。

6.下列程序判‎断字符串s‎是否对称,对称则返回‎1,否则返回0‎;如 f("abba")返回1,f("abab")返回0;int f((1)__ _____‎_){int i=0,j=0;while‎(s[j])(2)___ _____‎;for(j--; i<j && s[i]==s[j]; i++,j--);retur‎n((3)___ ____)}7.下列算法实‎现求采用顺‎序结构存储‎的串s和串‎t的一个最‎长公共子串‎。

《第4章串》习题解答分析

《第4章串》习题解答分析

第四章串存储与基本操作的实现本章学习要点◆熟悉串的相关概念以及串与线性表的关系◆重点掌握串的定长存储、堆分配存储的表示方法与基本操作的实现◆了解串的各种存储结构,能根据需要合理选用串的存储结构解决实际问题“串”(string),是字符串的简称,它是一种特殊的线性表,其特殊性在于组成线性表的数据元素是单个字符。

字符串在计算机处理实际问题中使用非常广泛,比如人名、地名、商品名、设备名等均为字符串。

同样在文字编辑、自然语言理解和翻译、源程序的编辑和修改等方面,都离不开对字符串的处理。

4.1串的基本概念4.1.1串的概念1.串的定义串(string) 是由n个字符组成的有限序列,记为:S=”a0a1a2…a n-1” (n≥0)。

其中,S是串的名字,字符序列a0a1a2…a n-1是串的值,a i(0≤i≤n-1)可以是字母、数字或其他字符元素;由于在C语言系统中数组元素的下标是从0开始的,所以串中所含元素的序号等于该元素的下标值加1;串中所含字符的个数n称为该串的长度,长度为0的字符串称为空串(null string)。

从串的定义可以看出,串实际上是数据元素为字符的特殊的线性表。

例如:(1)A=“X123” (长度为4的串)(2)B=“12345654321” (长度为11的串)(3)C=“Bei Jing” (长度为8的串)(4)D=“” (长度为0的空串)(5)E=“This is a string” (长度为16的串)(6)F=“ is a ” (长度为6的串)2.子串、主串和位置串中任意连续的字符组成的子序列称为该串的子串;相应地,包含子串的串称为主串。

串中的字符在串序列中的序号称为该字符在该串中的位置;子串的第一个字符在主串中的位置称为子串在主串中的位置。

显然,串为其自身的子串,并规定空串为任何串的子串。

显然,在不考虑空子串的情况下,一个长度为n的字符串具有n(n+1)/2个子串。

例如:在上例的(6)中串F就是(5)中串E的子串,且子串F在主串E中的位置是5。

数据结构(Java)-第4章

数据结构(Java)-第4章

Neusoft
NEXT
4、串的运算
(1)求串长:length() 初始条件:串已存在 操作结果:返回串中字符的个数。 (2)求子串:subString(begin,end) 初始条件:串已存在 操作结果:返回串中的一个子串,从第begin个字符开始,到第end个字 符结束。 (3)子串查找:patternMatching(str) 初始条件:串已存在
NEXT
五、 串项目实践
编制一个GUI程序演示串类的功能。包含如下操作:求串的 长度、求子串、模式匹配、串的插入、串的删除等。
Neusoft
NEXT
Neusoft
操作结果:返回子串str在主串中首次出现的索引位置。
NEXT
(4)串连接:concat(str)
初始条件:2个串已存在。
操作结果:将str串连接到当前串的结尾,当前串的值发生变化。 (5)串比较:compare(str) 初始条件: 2个串已存在。 操作结果: 将当前串与str串的串值进行比较。若二者值相等,则返回0;若当前串 值大于str串值,则返回一个正整数;若当前串值小于str串值,则返回一个负整数 。
int compare(SeqString str);
SeqString insert(int offset,SeqString str); SeqString delete(int begin,int end); }
Neusoft
NEXT
二、串的存储结构
1、串的顺序存储
采用一组地址连续的存储单元来存储串的字符序列,在Java语言中,用 字符数组实现。例如,串s = “Neusoft”的顺序存储如图所示。
2、删除操作
删除操作是指将当前串从begin开始到end-1结束的若干个串值删掉。

数据结构java语言描述课后答案

数据结构java语言描述课后答案

数据结构 java 语言描述课后答案【篇一:数据机构第一章—— java 语言描述第 1 章绪论习题参考答案】概念题1.试述下列各组概念:⑴数据、数据元素、数据项⑵ 数据结构、数据的逻辑结构、数据的存储结构⑶ 数据类型、数据操作⑷ 算法、算法的时间复杂度、算法的空间复杂度参考答案 : 略2 .试述数据结构研究的3 个方面的内容。

参考答案:数据结构研究的 3 个方面分别是数据的逻辑结构、数据的存储结构和数据的运算(操作)。

3.试述集合、线性结构、树型结构和图型结构四种常用数据结构的特性。

参考答案 :集合结构:集合中数据元素之间除了“同属于一个集合”的特性外,数据元素之间无其它关系,它们之间的关系是松散性的。

线性结构:线性结构中数据元素之间存在“一对一”的关系。

即若结构非空,则它有且仅有一个开始结点和终端结点,开始结点没有前趋但有一个后继,终端结点没有后继但有一个前趋,其余结点有且仅有一个前驱和一个后继。

树形结构:树形结构中数据元素之间存在“一对多”的关系。

即若结构非空,则它有一个称为根的结点,此结点无前驱结点,其余结点有且仅有一个前驱,所有结点都可以有多个后继。

图形结构:图形结构中数据元素之间存在“多对多”的关系。

即若结构非空,则在这种数据结构中任何结点都可能有多个前驱和后继。

4 .设有数据的逻辑结构的二元组定义形式为b=(d,r) ,其中d={a1,a2,?,an},r={ai,ai+1| i=1,2,?,n-1},请画出此逻辑结构对应的顺序存储结构和链式存储结构的示意图。

参考答案 :顺序存储结构示意图如下:0 1 2 ?n-2 n-1链式存储结构示意图如下:?5 .设一个数据结构的逻辑结构如图 1.9 所示,请写出它的二元组定义形式。

图 1.9 第 5 题的逻辑结构图参考答案 :它的二元组定义形式为 b= (d ,r ),其中d={k1,k2,k3,k4,k5,k6,k7,k8,k9},r=k1,k3,k1,k8,k2,k3k2,k4,k2,k5,k3,k9,k4,k6,k4,k7,k5,k6,k8,k9,k9,k7 } 。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

习题四参考答案一、选择题1.下面关于串的叙述中,哪一个是不正确的?(B )A.串是字符的有限序列B.空串是由空格构成的串C.模式匹配是串的一种重要运算D.串既可以采用顺序存储,也可以采用链式存储2.串的长度是指( A )A. 串中包含的字符个数B. 串中包含的不同字符个数C. 串中除空格以外的字符个数D. 串中包含的不同字母个数3.设有两个串p和q,其中q是p的子串,求q在p中首次出现的位置的算法称为( C )A.求子串B.联接C.模式匹配D.求串长4.设主串的长度为n,模式串的长度为m,则串匹配的KMP算法时间复杂度是( C )。

A. O(m)B. O(n)C. O(n + m)D. O(n×m)5. 串也是一种线性表,只不过( A )。

A. 数据元素均为字符B. 数据元素是子串C. 数据元素数据类型不受限制D. 表长受到限制6.设有一个10阶的对称矩阵A,采用压缩存储方式,以行序为主进行存储,a11为第一元素,其存储地址为1,每个元素占一个地址空间,则a85的地址为( B )。

A. 13B. 33C. 18D. 407. 有一个二维数组A[1..6, 0..7] ,每个数组元素用相邻的6个字节存储,存储器按字节编址,那么这个数组占用的存储空间大小是(D )个字节。

A. 48B. 96C. 252D. 2888.设有数组A[1..8,1..10],数组的每个元素占3字节,数组从内存首地址BA开始以列序为主序顺序存放,则数组元素 A[5,8]的存储首地址为( B )。

A. BA+141B. BA+180C. BA+222D. BA+2259. 稀疏矩阵的三元组存储表示方法( B )A. 实现转置操作很简单,只需将每个三元组中行下标和列下标交换即可B. 矩阵的非零元素个数和位置在操作过程中变化不大时较有效C. 是一种链式存储方法D. 比十字链表更高效10. 用十字链表表示一个稀疏矩阵,每个非零元素一般用一个含有( A )域的结点表示。

A.5B.4C. 3D. 2二、填空题1.2.串长度为03.4.5. 模式串t="ababaab"的next[]nextval[]数组值为。

6. 设数组A[1..5,1..6]的基地址为1000,每个元素占5个存储单元,若以行序为主序顺序存储,则元素A[5,5]7.在稀疏矩阵的三元组顺序表存储结构中,除表示非零元的三元组表以外,还需要表示矩阵的行数、列数和8.一个n×n的对称矩阵,如果以相同的元素只存储一次的原则进行压缩存储,则其元素压910.三、算法设计题1.编写基于SeqString类的成员函数count(),统计当前字符串中的单词个数。

参考答案:public int count() {int wordcount = 0; //单词个数char currChar, preChar;for (int i = 1; i < this.length(); i++) {currChar = this.charAt(i); //当前字符preChar = this.charAt(i - 1); //前一个字符if (((int) (currChar) < 65 || (int) (currChar) > 122//当前字符不是字母|| ((int) (preChar) > 90 && (int) (preChar) < 97))&& (((int) (preChar) >= 65 && (int) (preChar) <= 90) //当前字符的前一个字符是字母|| ((int) (preChar) >= 97 && (int) (preChar) <= 122))) { wordcount++;}}return wordcount;}2.编写基于SeqString类的成员函数replace(begin,s1,s2)。

要求在当前对象串中,从下标begin开始,将所有的s1子串替换为s2串。

参考答案://begin int 开始位置;s1 String 原始字符串; s2 String 目标字符串;public SeqString replace(int begin, SeqString s1, SeqString s2) {if (s1 == null || s2 == null) {return null;}SeqString ss = new SeqString(""); //产生空串SeqString source = this;int index = -1;while ((index = source.indexOf(s1, begin)) != -1) {ss.concat(source.substring(0, index)); //串连接ss.concat(s2);source = (SeqString) source.substring(index + s1.length());//取子串}ss.concat(source); //串连接return ss;}3.编写基于SeqString类的成员函数reverse()。

要求将当前对象中的字符反序存放。

参考答案:public SeqString reverse() {for (int i = 0, j = this.length() - 1; i < j; i++, j--) {char temp = this.charAt(i);setCharAt(i, this.charAt(j));setCharAt(j, temp);}return this;}4.编写基于SeqString类的成员函数deleteallchar(ch)。

要求从当前对象串中删除其值等于ch的所有字符。

参考答案:public SeqString deleteAllChar(char ch) {SeqString s1 = new SeqString(String.valueOf(ch));if (s1 == null) {return null;}SeqString ss = new SeqString(""); //产生空串SeqString source = this; //当前串赋值到sourseint index = -1;while ((index = source.indexOf(s1, 0)) != -1) {ss.concat(source.substring(0, index)); //串连接source = (SeqString) source.substring(index + 1); //取子串}ss.concat(source); //串连接return ss;}5.编写基于SeqString类的成员函数stringcount(str)。

要求统计子串str在当前对象串中出现的次数,若不出现则返回0。

参考答案:public int stringCount(SeqString str) {SeqString source = this.curstr;int count = 0, begin = 0;int index;while ((index = source.indexOf(str, begin)) != -1) {count++;begin = index + str.length();}return count;}6.鞍点是指矩阵中的元素a ij是第i行中值最小的元素,同时又是第j列中值最大的元素。

试设计一个算法求矩阵A的所有鞍点。

参考答案://存放矩阵中鞍点的类class Result {TripleNode data[]; //三元组表,存放鞍点的行、列、值int nums; //鞍点个数public Result(int maxSize) { //构造方法data = new TripleNode[maxSize]; //为顺序表分配maxSize个存储单元for (int i = 0; i < data.length; i++) {data[i] = new TripleNode();}nums = 0;}}//返回矩阵中的所有鞍点public Result allSaddlePoint(int[][] ar) {int i, j, flag, m, n;Result re = new Result(ar.length);for (i = 0; i < ar.length; i++) {m = i;n = 0;flag = 1; //假设当前结点是鞍点for (j = 0; j < ar[i].length; j++) {if (ar[i][j] < ar[m][n]) {n = j;}}for (j = 0; j < ar.length; j++) {if (ar[j][n] > ar[m][n]) {flag = 0; //不是鞍点}}if (flag == 1) { //是鞍点,将其加入re.data[re.nums] = new TripleNode(m, n, ar[m][n]);re.nums++;}}return re;}7.设计算法,求出二维数组A[n,n]的两条对角线元素之和参考答案:public static int sumOfDiagonal(int[][] a) {int i, n = a[0].length, sum1 = 0, sum2 = 0, sum;for (i = 0; i < a.length; i++) {sum1 += a[i][i]; //主对角线之和sum2 += a[i][n - i - 1]; //副对角线之和}sum = sum1 + sum2;if (n % 2 == 1) { //若矩阵行数为奇数,则减去两条对角线相交的元素。

sum -= a[n / 2][n / 2];}return sum;}四、上机实践题1. 在顺序串类SeqString中增加一个主函数,测试各成员函数的正确性。

参考答案:package ch04Exercise;import ch04.SeqString;public class Exercise4_4_1 extends SeqString{public static void main(String args[]) {char[] chararray = {'W', 'o', 'r', 'l', 'd'};SeqString s1 = new SeqString(); //构造一个空串SeqString s2 = new SeqString("Hello"); //以字符串常量构造串对象 SeqString s3 = new SeqString(chararray); //以字符数组构造串对象System.out.println("串 s1=" + s1 + ", s2=" + s2 + ", s3=" + s3);s1.insert(0, s2);System.out.println("串s1在第0个字符前插入串s2后,s1=" + s1);s1.insert(1, s3);System.out.println("串s1在第1个字符前插入串s3后,s1=" + s1);s1.delete(1, 4);System.out.println("串s1删除第1到第3个字符后,s1=" + s1);System.out.println("串s1中从第2到第5个字符组成的子串是:" + s1.substring(2, 6));}}运行结果:2. 已知两个稀疏矩阵A和B,试基于三元组顺序表或十字链表的存储结构,编程实现A+B的运算。

相关文档
最新文档