数据结构(C语言)第四章 字符串
严蔚敏数据结构-第四章 串

15
(2)S1串长 最大串长 串长<最大串长 串长 最大串长; S1,S2串长和 最大串长 串长和>最大串长 串长和 最大串长;
S1 6 a b c d e f S2 6 g h i j k l T 8 a b c d e f g h
3
串的抽象数据类型的定义: 串的抽象数据类型的定义: ADT String{ 数据对象: 数据对象:D={ai|ai∈CharacterSet, i=1,2,...,n, n>=0} 数据关系: 数据关系:R1={<ai-1,ai>|ai-1,ai∈D, i=2,...,n} 基本操作: 基本操作: StrAssign(&T, chars)
11
作业: 作业: 1.用5种串的基本操作(StrAssign、StrCompare、StrLen Concat、SubString)来逻辑实现StrInsert(&S, pos, T)操作 、 操作. )
Status StrInsert(String S, int pos , String T) { if ……….. return error; , , ); ); ); );
chars是字符串常量。生成一个其值等于chars的串 。 是字符串常量。生成一个其值等于 的串T。 是字符串常量 的串
StrCopy(&T, S)
存在则由串S复制得串 串S存在则由串 复制得串 存在则由串 复制得串T
StrEmpty(S)
存在则若S为空串 串S存在则若 为空串 返回真否则返回假 存在则若 为空串,返回真否则返回假
Sub返回串 的第pos个字符起长度为 返回串S的第 个字符起长度为len的子串 用Sub返回串S的第pos个字符起长度为len的子串
严蔚敏《数据结构(c语言版)习题集》答案第四章 串

林银花
一、教材说明:
1、 课题:《一定能摸到红球吗?》
2、 本节内容的地位和作用
在现代社会中,人们面临着更多的机会和选择,常常需要在不确定情境中作出合理的决策,概率正是通过对不确定现象和事件发生的可能性的刻画,来为人们更好的制定决策提供依据和建议.本节内容又是义务教育阶段,唯一培养学生从不确定的角度来观察世界的数学内容,让学生了解可能性是普遍的,有助于他们理解社会,适应生活.
(1) 每位同学从盒子中轮流摸球,记录下所摸球的颜色,并将球放回盒中.
(2) 做10次这样的活动,将最终结果填在表中.
(3) 全班将各小组活动进行汇总,摸到红球的次数是多少?摸到黄球的次数是多少?他们各占总数的百分比是多少?
(4) 你认为哪种颜色的球多?打开看一看.
(5) 如果从盒中任意摸出一球,你认为摸到哪种颜色的球可能性大? 学生阅读学习目标.
学生两人一组进行活动.一人摸一人记录.并交流.
题(1):学生先想象后画图,并通过搭建几何体验证学习成果。
题(2):学生四人一组进行活动,一人搭几何体,另三人画图并交流,如有异义,举手询问。依次轮流。 使学生明确学习目标,进入学习角色,做到有的放矢。
目的是使学生体会到进行概率试验时,一定要保证随机性.
课堂组织策略:创设贴近学生生活,生动有趣的问题情境,开展活泼、主动、有效的数学活动,组织学生主动参与、勤于动手、积极思考,使他们在自主探索和合作交流的过程中真正理解和掌握概率有关内容。
学生学习策略:明确学习目标,了解所需掌握的知识,在教师的组织、引导、点拨下主动地从事观察、试验、猜测、验证与交流等数学活动,从而真正有效地理解和掌握知识。
(3)、情感目标:
《数据结构与算法(C++语言版)》第4章_串

串函数与串的类定义
• 常用的 常用的C++串函数 串函数 • C++的串库(string.h)中提供了许多字符串的操作函数,几 个常用的C++字符串函数及其使用方法如下。 •假设已有以下定义语句:
串函数与串的类定义
• (1)串拷贝函数 • char *strcpy(char *s1, const char *s2),将字符串s2复制到字 符串数组s1中,返回s1的值。 • char *strncpy(char *s1, const char *s2, size_tn)将字符串s2中最 多n个字符复制到字符串数组s1中,返回s1的值。 • 例如:
串函数与串的类定义
• (3)串比较函数 • int strcmp(const char *s1, const char *s2),比较字符串s1和字 符串s2。函数在s1等于、小于或大于s2时,分别返回0、小 于0或者大于0的值。 • int strncmp(const char *s1, const char *s2, size_tn)比较字符串 s1中的n个字符和字符串s2。函数在s1等于、小于或大于s2 时,分别返回0、小于0或者大于0的值。 • 例如:
串模式匹配
• 无回溯的匹配算法 • 在上面介绍的匹配算法中,某趟匹配失败时,下一趟的匹 配相当于将子串P后移1位再从头与主串中对应字符进行比 较,即相当于i指示器回溯到上趟(最近失败的一趟)匹配 的起点的下一个位置,这样,主串中每个字符都要与子串 中的第1个字符对应一次,再向后比较。因此,主串中每个 字符参加比较的次数最多可达n次(n为子串长度),因此 时间复杂度为O(nm)。那么,能否使目标串中每个字符只参 加一次比较呢?也就是说,能否不回溯i指示器?回答是肯 定的。这个问题是由D.E.Knoth与V.R.Pratt和J.H.Morris同时 解决的,所以有的文献也称这种思想的串匹配算法为KMP 算法。
严蔚敏数据结构课后习题及答案解析

严蔚敏数据结构课后习题及答案解析数据结构课程是计算机科学与技术专业中非常重要的一门基础课程,对于学习者来说,课后习题的巩固和答案解析是学习的重要辅助材料。
本文将针对严蔚敏老师所著的《数据结构(C语言版)》中的课后习题及答案解析进行介绍和总结。
1. 第一章:绪论(略)2. 第二章:线性表(略)3. 第三章:栈和队列3.1 课后习题3.1.1 课后习题一:给定一个整数序列,请设计一个算法,其中删除整数序列中重复出现的元素,使得每个元素只出现一次。
要求空间复杂度为O(1)。
3.1.2 课后习题二:使用栈操作实现一个队列(其中队列操作包括入队列和出队列)。
3.2 答案解析3.2.1 答案解析一:我们可以使用双指针法来实现这一算法。
设定两个指针,一个指向当前元素,另一个指向当前元素的下一个元素。
比较两个元素是否相等,如果相等,则删除下一个元素,并移动指针。
如果不相等,则继续移动指针。
这样,当指针指向序列的最后一个元素时,算法结束。
空间复杂度为O(1),时间复杂度为O(n)。
3.2.2 答案解析二:使用两个栈来实现一个队列。
一个栈用于入队列操作,另一个栈用于出队列操作。
当需要入队列时,将元素直接入栈1。
当需要出队列时,判断栈2是否为空,如果为空,则将栈1中的元素逐个弹出并压入栈2中,然后从栈2中弹出栈顶元素。
如果栈2非空,则直接从栈2中弹出栈顶元素。
这样,就可以实现使用栈操作来实现队列操作。
4. 第四章:串(略)5. 第五章:数组和广义表(略)6. 第六章:树和二叉树(略)7. 第七章:图(略)通过对严蔚敏老师所著《数据结构(C语言版)》中的课后习题及答案解析的介绍,可以帮助学习者更好地理解和掌握数据结构这门课程的知识内容。
课后习题不仅可以帮助巩固所学知识,更加于提升学习者的能力和应用水平。
希望本文对于学习者们有所帮助。
(文章结束)。
数据结构_(严蔚敏C语言版)_学习、复习提纲.

期末复习 第一章 绪论 复习1、计算机算法必须具备输入、输出、可行性、确定性、有穷性5个特性。
2、算法分析的两个主要方面是空间复杂度和时间复杂度。
3、数据元素是数据的基本单位。
4、数据项是数据的最小单位。
5、数据结构是带结构的数据元素的集合。
6、数据的存储结构包括顺序、链接、散列和索引四种基本类型。
基础知识数据结构算 法概 念逻辑结构 存储结构数据运算数据:计算机处理的信息总称 数据项:最小单位 数据元素:最基本单位数据对象:元素集合数据结构:相互之间存在一种或多种特定关系的数据元素集合。
概念:数据元素之间的关系 线性结构:一对一非线性结构 树:一对多 图:多对多顺序存储结构 链表存储结构 索引。
散列。
算法描述:指令的有限有序序列算法特性 有穷性 确定性 可行性 输入 输出 算法分析时间复杂度 空间复杂度第二章 线性表 复习1、在双链表中,每个结点有两个指针域,包括一个指向前驱结点的指针 、一个指向后继结点的指针2、线性表采用顺序存储,必须占用一片连续的存储单元3、线性表采用链式存储,便于进行插入和删除操作4、线性表采用顺序存储和链式存储优缺点比较。
5、简单算法第三章 栈和队列 复习线性表顺序存储结构链表存储结构概 念基本特点基本运算定义逻辑关系:前趋 后继节省空间 随机存取 插、删效率低 插入 删除单链表双向 链表 特点一个指针域+一个数据域 多占空间 查找费时 插、删效率高 无法查找前趋结点运算特点:单链表+前趋指针域运算插入删除循环 链表特点:单链表的尾结点指针指向附加头结点。
运算:联接1、 栈和队列的异同点。
2、 栈和队列的基本运算3、 出栈和出队4、 基本运算第四章 串 复习栈存储结构栈的概念:在一端操作的线性表 运算算法栈的特点:先进后出 LIFO初始化 进栈push 出栈pop队列顺序队列 循环队列队列概念:在两端操作的线性表 假溢出链队列队列特点:先进先出 FIFO基本运算顺序:链队:队空:front=rear队满:front=(rear+1)%MAXSIZE队空:frontrear ∧初始化 判空 进队 出队取队首元素第五章 数组和广义表 复习串存储结构运 算概 念顺序串链表串定义:由n(≥1)个字符组成的有限序列 S=”c 1c 2c 3 ……cn ”串长度、空白串、空串。
数据结构习题集答案(C语言版严蔚敏)第四章串

第四章串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_nextLStrNode * 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))。
数据结构第四章:串

例2、串的定位 、串的定位index(s,t,pos)
在主串s中取从第 个字符起、 相等的子串和T比较 在主串 中取从第pos个字符起、长度和串 相等的子串和 比较,若 中取从第 个字符起 长度和串T相等的子串和 比较, 相等,则求得函数值为i,否则值增1直至 中不存在和串T相等的子串 直至S中不存在和串 相等,则求得函数值为 ,否则值增 直至 中不存在和串 相等的子串 为止。 为止。
}
4.2 串的表示和实现
首先强调:串与线性表的运算有所不同,是以“串的整体” 首先强调:串与线性表的运算有所不同,是以“串的整体”作 为操作对象,例如查找某子串, 为操作对象,例如查找某子串,在主串某位置上插入一个子串 等。 串有三种机内表示方法: 串有三种机内表示方法:
定长顺序存储表示
顺序 存储 ——用一组地址连续的存储单元存储串值的字 用一组地址连续的存储单元存储串值的字 符序列, 静态存储方式 方式。 符序列,属静态存储方式。
4.1 串类型的定义 4.2 串的表示和实现
4.1 串的类型定义
4.1.1串的定义
定义:串(string)是由零个或多个任意字符组成的字 符序列,是数据元素为单个字符的特殊线性表。 的特殊线性表。 是数据元素为单个字符的特殊线性表 记为:an”
(n≥0 )
第4章 串(String) 章 )
本章主题:串的各种基本运算及其实现 本章主题: 教学目的:了解数据结构的基本概念, 教学目的:了解数据结构的基本概念,理解常用术语 教学重点: 教学重点: 掌握串的基本概念及其基本运算 掌握串的存储结构 主要内容: 主要内容: 1.串的基本概念 2.串的存储结构 2.串的存储结构 3.串的基本运算及其实现 3.串的基本运算及其实现
串其中0<=pos<=strlen(s)-1,且数组 且数组sub至少可容纳 至少可容纳len+1个字符。*/ 个字符。 串其中 且数组 至少可容纳 个字符
数据结构c语言版 (4)

8. 在具有n个单元的循环队列中,队满时共有 ____个元素。 9. 一个栈的输入序列是12345,则栈的输出序 列43512是____。 10.二维数组A[10..20][5..10]采用行序为主方式 存储,每个元素占4个存储单元,并且 A[10][5]的存储地址是1000,则A[18][9]的地 址是____。 四、设有一个顺序栈S,元素s1, s2, s3, s4 , s5, s6依次进栈,如果6个元素的出栈顺 序为s2, s3, s4, s6, s5, s1,则顺序栈 的容量至少应为多少?
子串的位置:子串在主串中第一次出现的第一个字 符的位置。 两个串相等:两个串的长度相等,并且各个对应的 字符也都相同。 a= “program” b= “Program” c= “pro” d= “program ”
串的基本操作:
(1) 创建串 StringAssign (s,string_constant)
a0 0 a0 1 ... a0 ,n 1
a1 0
a1 1
...
a1 ,n 1
...
...
a m1 ,0
a m1 ,1
...
a m-1 , n 1
第0行
a0 0 a1 0 ... a m1 ,0
第1行
a0 1 a1 1 ... a m-1 ,1 ... ... a 0 ,n -1
第m-1行
a 1 ,n -1 ... a m1 ,n -1
矩阵的压缩存储
为多个值相同的元素只分配一个存储空间,对0元 素不分配空间。
1.对称矩阵
aij=aji
K=
{
矩阵的压缩存储
2. 三角矩阵 b. 上三角矩阵
K=
{
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Insert (S, i, T)
初始条件:串S和T存在,
1≤i≤StrLength(S) 操例如作:结S果=:c在ha串teSr的第,Ti个= 字r符ac之,后
则执行 Insert(插S,入4串, T。) 之后得 S = chatracer
Delete (S, i,
初始条件:串S存在
存储密度
=
数据元素所占存储位 实际分配的存储位
#define CHUNKSIZE 80 // 可由用户定义块
大小
typedef struct Chunk { // 结点结 构
char ch[CUNKSIZE]; struct Chunk *next; } Chunk; typedef struct { // 串的链表结构 Chunk *head, *tail; // 串的头和尾 指针
typedef unsigned char String [MAX
// 0号单元存放串的长度
特点:
串的实际长度可在这个予定义 长度的范围内随意设定,超过予定 义长度的串值则被舍去,称之为 “截断”
按这种串的表示方法实现的串 的运算时,其基本操作为 “字符序 列的复制”
二、串的堆分配存储表示
typedef struct { char *ch;
初始条件:串 S 和 T 存在。
操作结果:若S T,则返回值 0;
若S T,则 返回值 0;
若S T,则 例如:StrCm返p(“回d值ata”0,。“state”) < 0
StrCmp(“cat”, “c串 S 存在。
操作结果:返回 S 的元 素个数,称为串的长度。
// 若是非空串,则按串实用长度分 //存储区,否则 ch 为NULL int curlen; // 串长度 } String;
通常,C语言中提供的串类型就是 以这种存储方式实现的。系统利用函数 malloc( ) 和 free( ) 进行串值空间的 动态管理,为每一个新产生的串分配一个 存储区,称串值共享的存储空间为“堆”。
操作结果: 若主串 S 中存在和串 T
值
相同的子串, 则返回它
在主串 S 中第一次出现的位置,否则
函数值为0。
“子串在主串中的位置”意指子串 中的第一个字符在主串中的位序。
假设 S = abcaabcaaabc , T = bca Index(S, T) = 2;
Replace (S, T, V)
4.2 串的存储结构
在程序设计语言中,串只 作为输入或输出的常量出现,则只 需存储此串的串值,即字符序列即 可。但在多数非数值处理的程序中, 串也以变量的形式出现。
一、串的定长顺序存储表示 二、串的堆分配存储表示 三、串的块链存储表示
一、串的定长顺序存储表示
#define MAXSTRLEN 255 // 用户可在255以内定义最大
主串:包含子串的串
字符在串中的位置:字符在序列中的序号
子串在串中的位置:子串的第一个字符在 主串中的位置
串的基本运算
• 串插入 值
• 求串长 较
• 串联接 子串
• 串定位
串赋 串比
求 串
StrAssign (T, chars)
初始条件:chars 是字符串常量。 操作结果:把 chars 赋为 T 的值。
C语言中的串以一个空字符为结束符, 串长是一个隐含值。
这类串操作实现的算法为:
先为新生成的串分配一个存储空间,然后 进行串值的复制。
三、串的块链存储表示
也可用链表来存储串值,由于串的数据 元素是一个字符,它只有 8 位二进制 数,因此用链表存储时,通常一个结点 中存放的不是一个字符,而是一个子串。
1≤i≤StrLen(S)
操作结果:从串S中删除第i个字符 起长度为j的子串
对于串的基本操作集可以有不同的 定义方法,在使用高级程序设计语言中的串 类型时,应以该语言的参考手册为准。
例如:C语言函数库中提供下列串处理函数:
gets(str) 输入一个串; puts(str) 输出一个串; strcat(str1, str2) 串联接函数; strcpy(str1, str2, k) 串复制函数; strcmp(str1, str2) 串比较函数; strlen(str) 求串长函数;
字符串 字符串:是 n(S(tri0n)g)个字符的有限序
列,
记作 S : “c1c2c3…cn” 其中,S 是串名字
“c1c2c3…cn”是串 值
ci 是串中字符 n 是串的长度。
例如, S = “Tsinghua University”
空串:零个字符的串称为空串 记作 “Ø”
子串:串中任意个连续的字符组成的子序 列
SubStr(“commander”, 4, 7) sub = ?
SubStr(“beijing”, 7, 2) = ? sub = ?
起始位置和子串长度之间存在约束关系
SubStr(student, 5, 0) =
长度为 0 的子串为“合法”串
Index (S, T)
初始条件:串S和T存在,T是非空串
Strcat ( S1, S2)
初始条件:串 S1 和 S2 存 在。
操作结果:返回由 S1 和 S2 联接
例如: St而rca成t(的新ma串n,。kind)
求得 S1 = mankind
SubStr( S, i, j)
初始串条件S :存在,1≤i≤StrLen(S)
且 0≤j≤StrLen(S) - i+1。
初始条件:串S, T和 V 均已存在, 且 T 是非空串。
操作结果:用 V 替换主串 S 中 出现 的所有与
(模式串)T 相等的子串。
例如: 假设 S = abcaabcaaabca, T = b 若 V = x , 则经置换后得到
S = axaxaax
若 V = bc , 则经置换后得到 S = abcabcaabc
操作结果:
返回串 S 的第 i个字符起 长度为 j的子串。
子串为“串”中的一个字符子序列 例如:
SubStr( commander , 4, 3) 求得 sub = man ;
SubStr(commander , 1, 9) 求得 sub = commander
SubStr( commander , 9, 1) 求得 sub = r