




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
栈和队列第4章数据结构(C语言版)可表示为:(a1,a2,……,an)第2章线性表第3章栈和队列(操作受限)第4章串(内容受限)、数组和广义表线性结构补充:C语言中常用的串运算串比较,strcmp(chars1,chars2)串复制,strcpy(charto,charfrom)串连接,strcat(charto,charfrom)求串长,strlen(chars)……调用标准库函数#include<string.h>掌握串的存储方法,掌握BF算法和KMP算法。明确数组和广义表这两种数据结构的特点,掌握数组地址计算方法,掌握几种特殊矩(对称矩阵,对角矩阵,三角矩阵,稀疏矩阵等)压缩存储方法。掌握广义表的求表头和求表尾基本操作。01OPTION02OPTION03OPTIONtarget目标目录导航4.14.24.34.44.54.64.7串案例引入串的类型定义、存储结构及运算数组广义表案例分析与实现LeetCode算法练习题Contents串的定义串(String)----零个或多个字符组成的有限序列。串名串值串长n空串n=0a=‘BEI’,b=‘JING’c=‘BEIJING’d=‘BEIJING’子串字符位置主串子串位置串相等空格串串的定义a、b、c、d的长度分别为3、4、7、8;a和b都是c和d的子串;a在c和d中的位置都是1;b在c中的位置都是4,在d中的位置是5。目录导航4.14.24.34.44.54.64.7串案例引入串的类型定义、存储结构及运算数组广义表案例分析与实现LeetCode算法练习题Contents研究人员不断从苹果、桑树等树种中检测到新的双生病毒案例引入--病毒感染检测参考文献:SunS,RenY,WangD,etal.AgroupIWRKYtranscriptionfactorregulatesmulberrymosaicdwarf‐associatedvirus‐triggeredcelldeathinNicotianabenthamiana[J].MolecularPlantPathology,2022,23(2):237-253.病毒DNA序列:单链环状树种DNA序列:为链状案例引入--病毒感染检测利用专业知识解决林草领域应用问题。培养农林信息化研究能力、创新精神、生态文明理念、绿色环保意识。研究者将病毒DNA和植物的DNA均表示成由字母组成的字符串序列。检测某种病毒DNA序列是否在植物的DNA序列中出现过。出现过,已感染未出现,未感染。案例引入--病毒感染检测baa感染bbbbaa感染aaabbb未感染babbbabaa案例引入--病毒感染检测
存在存在未存在bbbbaaaaabbbbabbba子串:baa主串1主串2主串3案例引入--病毒感染检测案例引入--模式匹配算法存在时,返回子串的位置。不存在,返回0。--检测一个主串中是否存在一个给定的子串(模式)模式匹配算法应用--网络入侵检测模式匹配算法应用--网络入侵检测模式匹配算法应用--网络入侵检测知法守法树立健康的网络道德观具有科技报国的社会责任感和爱国主义情操严谨求实、勇于创新“共建网络安全,共享网络文明“网络安全人人有责、人人参与模式匹配算法应用--网络入侵检测模式匹配算法应用--网络入侵检测根据入侵行为的特征,按照一定的规范将这些特征编写成规则。通过检测网络数据与规则数据库中的规则是否匹配,来判断入侵与否。模式匹配算法应用--信息检索模式匹配算法应用--信息检索模式匹配算法——Index(S,T,p)初始条件1≤p≤StrLength(S)操作结果主串S中是否存在子串T:存在,返回S中的第p个字符之后T第一次出现的位置;不存在,返回0。目录导航4.14.24.34.44.54.64.7串案例引入串的类型定义、存储结构及运算数组广义表案例分析与实现LeetCode算法练习题Contents串的类型定义、存储结构及运算数据对象:数据关系:基本操作:(1)StrAssign(&T,chars)//串赋值(2)StrCompare(S,T)//串比较(3)StrLength(S)//求串长(4)Concat(&T,S1,S2)//串联ADTString{(5)SubString(&Sub,S,pos,len)//求子串
(6)StrCopy(&T,S)//串拷贝
(7)StrEmpty(S)//串判空
(8)ClearString(&S)//清空串
(9)Index(S,T,p)//子串的位置
(11)Replace(&S,T,V)//串替换
(12)StrInsert(&S,pos,T)//子串插入
(12)StrDelete(&S,pos,len)//子串删除
(13)DestroyString(&S)//串销毁}ADTString串的类型定义、存储结构及运算串的存储结构链式存储顺序存储#defineMAXLEN255//串的最大长度typedefstruct{charch[MAXLEN+1];//存储串的一维数组intlength;//串的当前长度}SString;
串的定长顺序存储结构typedefstruct{char*ch;//若串非空,则按串长分配存储区,//否则ch为NULLintlength;//串长度}HString;
串的堆式顺序存储结构链式存储表示#defineCHUNKSIZE80//可由用户定义的块大小typedefstructChunk{charch[CHUNKSIZE];
structChunk*next;}Chunk;typedefstruct{Chunk*head,*tail;//串的头指针和尾指针
intcurlen;//串的当前长度}LString;串的链式存储结构优点:操作方便。缺点:存储密度较低。可将多个字符存放在一个结点中,以克服其缺点。实际分配的存储位串值所占的存储位存储密度=链式存储表示串的模式匹配算法算法目的:算法种类:AB确定主串中所含子串第一次出现的位置(定位)。BF算法(又称古典的、经典的、朴素的、穷举的)KMP算法(特点:速度快)S:ababcabcacbabT:abcijS:ababcabcacbab T:abcS:ababcabcacbabT:abci
指针回溯模式匹配算法——BF(BruteForce)算法——穷举、经典、古典算法BF算法步骤执行循环:将主串的第p个字符和子串的第1个字符比较相等,继续逐个比较后续字符;不等,回溯到主串的下一个字符,重新与子串的第1个字符比较。退出循环成功:返回S中与T匹配的子序列第1个字符的序号;失败:返回0。
intIndex_BF(SStringS,SStringT,intp)i=p;j=1; while(i<=S.length&&j<=T.length))
//两个串均未到达串尾{if(S.ch[i]==T.ch[j]){++i;++j;}
//相等,继续比较后续字符
else{i=i-j+2;;j=1;}
//不等,指针后退重新开始匹配}if(j>T.length)returni-T.length;
//成功elsereturn0;
//失败
}?i=i-j+2BF算法实现
BF算法分析--算法分析S:aaaaabaT:aaaaaaaaabaaaba主串S长n,子串T长m?可能匹配成功的位置(1~)n-m+1aaaaabaaaaaaaaaaabaaaaabaaaaabaaaaban=7,m=5
BF算法分析--最好情况(平均)每趟不成功的匹配都发生在T的第一个字符与S相应字符的比较。第i个位置匹配成功,比较了(i-1+m)次假定每个位置上匹配成功的概率相等S:aaaaabaT:ba则平均比较次数最好情况下平均时间复杂度O(n+m)
BF算法分析--最坏情况(极端)aaaaaabaabaaaaaabaab1234567aaaaaabaab第5个位置匹配成功比较了次???(5−1)*3+3=5*3=15——子串位于主串的末尾(i−1)*m+m=i*maaaaaabaabaaaaaabaabn=7,m=3最后一个位置匹配成功比较了次???(7−3)*3+3=5*3=15(n-m)*m+m=(n-m+1)*m
每趟不成功的匹配都发生在T的最后一个字符与S相应字符的比较第i个位置匹配成功,比较了i*m次假定每个位置上匹配成功的概率相等则平均比较次数最坏情况下平均时间复杂度O(n*m)(通常m<<n)BF算法分析--最坏情况
baa感染bbbbaa感染aaabbb未感染babbbabaa--BF算法循环m次如何取得每个长度为m的环状字符串?案例实现--病毒感染检测案例实现--病毒感染检测baabaabaabaabaaaabababaa依次检测每对病毒DNA和人的DNA是否匹配,循环执行:分别读取一对病毒DNA序列和人的DNA序列;设置flag,初始为0,表示未匹配;病毒DNA长度是m,连续存储两次扩大为2m;循环m次,重复执行以下操作:依次取得每个长度为m的病毒DNA环状字符串;将此字符串作模式串,将人的DNA作主串,调用BF,将结果返回flag;若flag非0,表示匹配成功。退出循环时,若flag非0,输出“YES”,否则,输出“NO”。案例实现--病毒感染检测案例实现--病毒感染检测医学研究者最近发现了某些新病毒,通过对这些病毒的分析,得知它们的DNA序列都是环状的。现在研究者收集了大量的病毒DNA和人的DNA数据,想快速检测出这些人是否感染了相应的病毒。为方便研究,研究者将人的DNA和病毒的DNA均表示成由一些小写字母组成的字符串,然后检测某种病毒的DNA序列是否在患者的DNA序列中出现过,如果出现过,则此人感染了病毒,否则没有感染。注意:人的DNA序列是线性的,而病毒的DNA序列是环状的。任务描述对于每组数据输出一行,若患者感染了病毒输出“YES”,否则输出“NO”。输入输出多组数据,每组数据有一行,为序列A和B,A对应病毒的DNA序列,B对应人的DNA序列。A和B都为“0”时输入结束。案例实现--病毒感染检测案例实现--网络入侵检测随着互联网的飞速发展,网络安全问题日益严重。入侵检测技术是一种积极主动防御的安全保障技术,而Snort是其中基于规则匹配的一种入侵检测技术。Snort自1998年被发明以来,历经数年的迭代更新,Snort已成为一个具有多平台(Multi-Platform)、实时(Real-Time)流量分析、网络IP数据包(Pocket)记录等特性的强大的网络入侵检测/防御系统(NetworkIntrusionDetection/PreventionSystem),即NIDS/NIPS。Snort首先需要使用者根据入侵行为的特征,按照一定的规范将这些特征编写成规则,最后通过检测网络数据与规则数据库中的规则是否匹配来判断入侵与否。在Snort入侵检测系统中,规则的匹配效率是影响Snort检测效率的关键。而规则匹配的核心技术是模式匹配算法。请实现一个模式匹配算法,用于网络入侵行为的检测。若检在网络日志中检测到任何一条检测规则中的ip地址,则输出“Networkintrusiondetected.”,反之输出“Nothingdetected.”任务描述案例实现--网络入侵检测输出一行,若在网络日志中检测到任何一条检测规则中的ip地址,则输出“Networkintrusiondetected.”,反之输出“Nothingdetected.”。输入输出输入共n+m+1行,第1行两个整数n,m(n,m≤100)2~n+1行每行为一条检测规则。规则的格式为:protocol:网络协议ip:ip地址msg:"附加信息"n+2~n+m+1行共m行,为网络日志内容。案例实现--网络入侵检测测试输入:`33``protocol:tcpip:225.93.118.39msg:"Networkintrusiondetected."``protocol:tcpip:152.213.218.150msg:"Networkintrusiondetected."``protocol:tcpip:181.164.101.231msg:"Networkintrusiondetected."``ProtoRecv-QSend-QLocal-AddressForeign-AddressState``tcp0036.51.200.67:9540340.56.49.213:29716LAST_ACK``tcp00215.142.133.153:49323106.54.135.230:18487CLOSED`预期输出:`No
Intrusion.`案例实现--网络入侵检测模式匹配算法小结模式匹配知真酌,入侵检测卫家国模拟数据无量着,
式子算法何其多。
匹配相合题相似,
配出相同知真灼。
入心付血辅新秀,
侵解内核吾存忧。
检验真知迎风浪,
测病防疫卫家国。S:ababcabcacbabT:abcijS:ababcabcacbab T:abcS:ababcabcacbabT:abci指针回溯BF算法低效KMP(KnuthMorrisPratt)算法《计算机程序设计艺术第1卷基本算法》
《计算机程序设计艺术第2卷半数值算法》《计算机程序设计艺术第3卷排序与查找》《计算机程序设计艺术第4卷组合算法》BF缺陷:s的指针i回溯,已经被检索过的部分主串被重复检索。同时,t的指针j也会回溯到起始位置。babcadcbcbcdijstKMP算法KMP改进:如何避免指针i回溯。在BF中,指针i回溯的目的?不回溯可能会错过一些匹配。KMP算法设计思想bcaaadcbcaadijstbcaaadcbcaadijstKMP算法设计思想指针i不动?子串向右滑动,即找到j移动的位置,使得新的指针j之前的字符能够自动匹配。j应该移动到的位置k有什么特点?abababcabaijstbckdeKMP算法设计思想abababcabaijstbckde
而滑动之前已匹配过的字符能告诉我们什么信息呢?KMP算法设计思想主串的k-1位后缀与子串的k-1位前缀相同!
abababcabaijstbcde
KMP算法设计思想只需要比较子串的前后缀就可以了,无需主串!最长相同前缀和后缀KMP算法设计思想
abajtbc
KMP算法设计思想KMP算法设计思想intindex_KMP(SStringS,SStringT,intpos){
i=pos;j=1;while(i<=S.length&&j<=T.length){if(j==0||S.ch[i]==T.ch[j])++i;++j;}elsej=next[j];}if(j>T.length)returni-T.length;elsereturn0;}若s[i]和t[j]相等,则比较s[i+1]和t[j+1]若s[i]和t[j]不等,则j回退到next[j]所指的位置k,继续比较s[i]和t[k];当s[i]和t[1]不等,则比较s[i+1]和t[1]所以next[1]=0。acabaabaaabbaaccab第一趟:从s[1]和t[1]开始匹配i=2j=2,j=next[2]=1下一次将会进行s[2]和t[1]的比较主串模式串此时发生失配aabcacj12345678模式串abaabcacnext[j]01122312KMP算法设计思想KMP算法设计思想acabaabaaabbaaccab第二趟:从s[2]和t[1]开始匹配i=2模式串此时发生失配aabcacj=1,j=next[1]=0下一步将会进行s[3]和t[1]的比较主串j12345678模式串abaabcacnext[j]01122312acabaabaaabbaaccab第三趟:从s[3]和t[1]开始匹配模式串aabcac主串i=8发生失配j=6,j=next[6]=3下一步将进行s[8]和t[3]的比较j12345678模式串abaabcacnext[j]01122312KMP算法设计思想acabaabaaabbaaccab第四趟:从s[8]和t[3]开始匹配模式串aabcac主串i=8j=9(j>8,匹配成功)j12345678模式串abaabcacnext[j]01122312KMP算法设计思想失配时,i不变,j回退next[j]重新匹配。当j退到0,i和j需要同时加1(即主串的第i个字符和模式的第1个字符不等时,应从主串的第i+1个字符起重新进行匹配)。KMP算法设计思想若next[j]=k,子串起始的k-1个字符与j之前的k-1个字符匹配。next[j]存储着指针j之前的字符信息,而与j所指字符无关。要保证j能够回溯,应该让k<j,有j-k+1>1,j之前这一组字符最多从第二个开始。KMP算法设计思想abajtbc
kfej=2时,需要用到next[2],意味着模式串已经向右滑动到j指向第2个字符,仍然不能与主串中i所指字符产生匹配。接下来需要让指针j回溯到1,再进行比较。此时会使用j=next[j],而next[2]正是用来存储需要回溯的位置,所以next[2]=1。KMP算法设计思想aabdcijsabdt用肉眼求一些next[]数值KMP算法设计思想1?????01123nextabcabcft已知next[j]=k,求next[j+1]的值当t[j]==t[k]时,next[j+1]=next[j]+1,也就是k+1。只要j对应的k是最大的,j+1对应的k+1也必然是最大的。KMP算法设计思想?4abcabcfj011123abc
tknext
k
j+1KMP算法设计思想已知next[j]=k,求next[j+1]的值当t[j]!=t[k]时,想要找到j+1之前最长的字符匹配,应该让模式串起始部分向右滑动到正确位置,然后对位置j的字符进行比较。那么应该滑动到什么位置呢??abcabafj011123abc
tknextkj+1如果把这里的整个模式串看做主串,模式串的起始部分看做子串,这正是一个主串与模式串匹配的过程。寻找子串向右滑动的位置,或者说指针k回溯的位置,这正是next[]数组的目的。答案显而易见:k=next[k]。KMP算法设计思想?abcabafj011123abc
tknextkj+1通过比较发现t[j]==t[k],那么next[j+1]就同样会等于k+1,只不过现在的k已经是回溯过后的。KMP算法设计思想?2abcabafj011123abc
tknextkj+1如果一次滑动不行,那就继续滑动,继续比较,可能直到滑动到头也没能找到匹配。KMP算法设计思想?abcabdfj011123abc
tknextkj+1挨着j+1这个位置之前,完全找不到任何能与起始部分匹配的字符。如果在j+1这个位置失配,即使不回溯i,也不会出现错过匹配的现象,直接从模式串的第一个位置开始匹配即可。next[j+1]=1,此时k=0,next[j+1]=k+1。KMP算法设计思想?1abcabdfj011123abc
tknextkj+1因为next[j]=k代表了j需要回溯的位置,所以j一定大于k。而在可能会进行的多次k=next[k]过程中,假设next[k]=k1,next[k1]=k2……同理可得j>k>k1>k2……只要知道了j+1之前的所有位置的next[]数值,就一定可以求出next[j+1]的数值。KMP算法设计思想?abcabdfj011123abc
tknextkk1k21j+1KMP算法设计思想voidget_next(SStringT,intnext[]){i=1;j=0;next[1]=0;while(i<T.length){if(j==0||T.ch[i]==T.ch[j]){++i;++j;next[i]=j;}elsej=next[j];}}t[i]=t[j],next[i+1]=j+1;//初始化t[i]≠t[j],j往前滑动到next[j]所指向的位置重复上述过程直到t[i]=t[j];若找不到,j最终会滑到0,next[i+1]=1。求出next[1]=0,next[2]=1这两个特殊起始位置的数值。通过循环,可以求出next[3]、next[4]……最终求出整个next[]数组。在这个过程中模式串t,既做了主串又做了模式串,求next[]的过程还是一个模式匹配的问题。以abaabc为例跟踪程序运行结果j=0—>i=2,j=1,next[2]=1下一步进行t[2]和t[1]的比较KMP算法设计思想abaabcabaabc主串模式串t[2]≠t[1],j=next[1]=0——>j=1,i=3,next[3]=1;下一次将会进行t[3]和t[1]的比较。t[3]和t[1]的比较KMP算法设计思想abaabcabaabc主串模式串t[3]=t[1]——>i=4,j=2,next[4]=2;下一步进行t[4]和t[2]的比较。t[4]≠t[2]——>j=next[2]=1;下一步进行t[4]和t[1]。t[4]和t[1]的比较KMP算法设计思想abaabcabaabc主串模式串t[4]=t[1]——>i=5,j=2,next[5]=2,下一步t[5]和t[2]会进行比较。t[5]=t[2]——>i=6,j=3,next[6]=3i=T.length循环结束KMP算法设计思想求next[k+1],其中k+1=17j1234567891011121413151617k+1pnext[j]KMP算法设计思想已知next[16]=8,则元素有以下关系:j1234567891011121413151617k+1Pnext[j]8若P8=P16,则next[17]=8+1=9这两部分重合KMP算法设计思想j1234567891011121413151617k+1Pnext[j]8若P8≠P16,且next[8]=4,则有以下关系:这两部分重合4这两部分重合KMP算法设计思想j1234567891011121413151617k+1Pnext[j]8若P8≠P16,且next[8]=4,则有以下关系:这两部分重合4这四部分重合KMP算法设计思想j1234567891011121413151617k+1Pnext[j]8若P8≠P16,且next[8]=44若P16=P4,则next[17]=4+1=5KMP算法设计思想j1234567891011121413151617k+1Pnext[j]8这两部分重合4这两部分重合若P16≠P4,若next[4]=2,则有以下关系:这两个数重合2KMP算法设计思想j1234567891011121413151617k+1Pnext[j]8这两部分重合4这两部分重合若P16=P2,则next[17]=2+1=3,否则继续取next[2]=1、next[1]=0;遇到0时还没有出结果,则递推结束,此时next[17]=1。这两个数重合2next数组的缺陷KMP算法设计思想aaabaaaabisaaajtab01234next前面全都是‘a’,却要一个一个全部和‘b’比较一次。KMP算法设计思想aaabaaaabisaaajtab01234next为什么会发生这种情况呢?KMP算法设计思想abcabxyisabcjtab01112next3cz当检测到‘c’和‘x’不同时,j会回溯为next[6]=3。此时t[j]仍为‘c’。已经得知‘c’!=‘x’,但仍需要再次判断后,才能让j回溯到正确的位置next[3]=1。KMP算法设计思想abcabxyisabcjtab01112next3cz发现t[6]=t[3]时,直接使next[6]=next[3]=1。next[]数组的修正值nextval[]:在j++以及k++之后,在向nextval[]数组中填入数值时,如果t[j]==t[k],直接使next[j]=next[k]即可。KMP算法设计思想abcitabnextval0c11111jvoidget_nextval(SStringT,intnextval[]){i=1;nextval[1]=0;j=0;while(i<T.length){if(j==0||T.ch[i]==T.ch[j]){++i;++j;
if(T.ch[i]!=T.ch[j])nextval[i]=j;elsenextval[i]==nextval[j];}elsej=nextval[j];}}voidget_next(SStringT,intnext[]){i=1;j=0;next[1]=0;while(i<T.length){if(j==0||T.ch[i]==T.ch[j]){++i;++j;next[i]=j;}elsej=next[j];}}KMP算法设计思想使用nextval[修正数组实现KMP算法时,不会出多次无用比较的现象。nextval数组中nextval[2]不一定等于1,且可能会有多个0出现。while(i<T.length){if(j==0||T.ch[i]==T.ch[j])
{++i;++j;if(T.ch[i]!=T.ch[j])nextval[i]=j;elsenextval[i]==nextval[j];
}elsej=nextval[j];}KMP算法设计思想aaaitabnextval00004j设主串长度为n,模式串长度为m,求nextval数组的过程循环了m-1次,与主串的匹配过程也比较了m次,最好时间复杂度为:O(m)。KMP算法时间复杂度---最好aaaabcdsaaaaitanextval0000jO(m+n)=O([m,2m]+[n,2n])
计算next数组的时间复杂度+遍历比较的复杂度1.当前字符匹配时,同时移动i++,j++;2.当前字符不匹配,且j=0时,只移动i++,j=0不动;3.当前字符不匹配,且j!=0时,i不变,strM[j]回跳,最多跳j次。但j由前面匹配的情况1确定,而情况1总共不可能出现超过n次,所以总回跳不会超过n次。最坏情况:i++次数(情况一+情况二)+j回跳(情况3)=n+最坏n=2n[m,2m]也可以类似证明KMP算法时间复杂度---最坏设主串s的长度为n,模式串t长度为m,在KMP算法中求next数组的时间复杂度为O(m),在后面的匹配中因主串s的下标不减即不回溯,比较次数可记为n,所以KMP算法总的时间复杂度为O(n+m)。KMP算法改进--BM(BoyerMoore)算法文献1:BoyerRS,MooreSJ.Afaststringsearchingalgorithm.CommunicationsoftheACM[J].1977,20(10):762-772.速度快于KMP3-4倍,用于文本编辑器的查找功能文献2:FengD.Aneffectivepatternmatchingalgorithmforintrusiondetection[C]//InternationalConferenceonComputerScience&ElectronicsEngineering.IEEE,2012.BM算法的改进目录导航4.14.24.34.44.54.64.7串案例引入串的类型定义、存储结构及运算数组广义表案例分析与实现LeetCode算法练习题Contents本节所讨论的数组与高级语言中的数组区别:数组高级语言中的数组是顺序结构;而本章的数组既可以是顺序,也可以是链式结构。数组的抽象数据类型数据对象:数据关系:ADTArray{(1)InitArray(&A,n,bound1,boundn)//构造数组A(2)DestroyArray(&A)//销毁数组A(3)Value(A,&e,index1,…,indexn)//取数组元素值
(4)Assign(A,&e,index1,…,indexn)//给数组元素赋值基本操作:}ADTArray数组的抽象数据类型一维数组352749186054778341020123456789ll
l
l
l
l
l
l
l
l
LOC(i)=LOC(i-1)+l=a+i*lLOC(i)=LOC(i-1)+l=a+i*l,i>0a,i
=0
a+i*la二维数组以行序为主序C,PASCAL数组的顺序存储以列序为主序FORTRAN数组的顺序存储
a[n][m]设数组开始存放位置LOC(0,0)=a
LOC(j,k)=a+j*m+k二维数组的行序优先表示三维数组按页/行/列存放,页优先的顺序存储
①②③a[m1][m2][m3]
各维元素个数为m1,m2,m3
下标为i1,i2,i3的数组元素的存储位置:
LOC(i1,i2,i3)=a+
i1*m2*m3+i2*m3+i3前i1页总元素个数第i1页的前i2行总元素个数第i2行前i3列元素个数三维数组各维元素个数为m1,m2,m3,…,mn下标为i1,i2,i3,…,in
的数组元素的存储位置:n维数组n维数组设有一个二维数组A[m][n]按行优先顺序存储,假设A[0][0]存放位置在644(10),A[2][2]存放位置在676(10),每个元素占一个空间,问A[3][3](10)存放在什么位置?脚注(10)表示用10进制表示。设数组元素A[i][j]存放在起始地址为Loc(i,j)的存储单元中∵Loc(2,2)=Loc(0,0)+2*n+2=644+2*n+2=676.∴n=(676-2-644)/2=15∴Loc(3,3)=Loc(0,0)+3*15+3=644+45+3=692.练习设有二维数组A[10,20],其每个元素占两个字节,A[0][0]存储地址为100,若按行优先顺序存储,则元素A[6,6]的存储地址为
,按列优先顺序存储,元素A[6,6]的存储地址为
。练习352232(6*20+6)*2+100=352(6*10+6)*2+100=232特殊矩阵的压缩存储12什么是压缩存储?若多个数据元素的值都相同,则只分配一个元素值的存储空间,且零元素不占存储空间。什么样的矩阵能够压缩?一些特殊矩阵,如:对称矩阵,对角矩阵,三角矩阵,稀疏矩阵等。什么叫稀疏矩阵?矩阵中非零元素的个数较少(一般小于5%)。3[特点]
在n×n的矩阵a中,满足如下性质:aij=aji(1≤i,j≤n)[存储方法]
只存储下(或者上)三角(包括主对角线)的数据元素
共占用n(n+1)/2个元素空间。
i(i-1)/2+j当i≥jj(j-1)/2+i当i<ja11a21a22a31
aij(aji)ann
k1234n(n+1)/2saajiaij1.对称矩阵k=2.三角矩阵
上三角矩阵下三角矩阵(i-1)(2n-i+2)/2+j-i+1i≤ji(i-1)/2+ji≥jn(n+1)/2+1i>j
n(n+1)/2+1i<jCC上三角矩阵下三角矩阵k=k=[特点]
对角线以下(或者以上)的数据元素(不包括对角线)全部为常数c。[存储方法]
重复元素c共享一个元素存储空间,共占用n(n+1)/2+1个元素
空间:
sa[1..n(n+1)/2+1]。3.对角矩阵(带状矩阵)
823000
420300
577680096915006142000283五对角矩阵
338520612827943476185962s[-2..2;1..6]-2-1012123456i1=i-jj1=j|i-j|(L-1)/2k1n*Lsak=(i1+2)*n+j1=(i-j+2)*n+j|i-j|(L-1)/2[特点]
在n×n的方阵中,非零元素集中在主对角线及其两侧共L(奇数)
条对角线的带状区域内—L对角矩阵。[存储方法]以对角线的顺序存储
823000
420300
577680096915006142000283823420357768969156142283sak12345678910111213141516171819202122232425263.对角矩阵(带状矩阵)只存储带状区内的元素除首行和末行,按每行L个元素,共(n-2)L+(L+1)个元素。sa[1..(n-1)L+1]k=(i-1)L+1+(j-i)|i-j|(L-1)/24.稀疏矩阵[特点]
大多数元素为零。6×6顺序存储:三元组表链式存储:十字(正交)链表
[常用存储方法]
只记录每一非零元素(i,j,aij)节省空间,但丧失随机存取功能。1500220-15011
3000000-600000000
91
000000028000目录导航4.14.24.34.44.54.64.7串案例引入串的类型定义、存储结构及运算数组广义表案例分析与实现LeetCode算法练习题Contents
LS是表名,ai是表元素,它可以是表(称为子表),可以是数据元素(称为原子)。n为表的长度。n=0的广义表为空表。广义表
广义表(列表):n(
0)个表元素组成的有限序列,记作LS=(a0,a1,a2,…,an-1)线性表的成分都是结构上不可分的单元素。广义表的成分可是单元素,也可是有结构的表。线性表是一种特殊的广义表。广义表不一定是线性表,也不一定是线性结构。广义表与线性表的区别?广义表的基本运算求表头GetHead(L)01非空广义表的第一个元素,可以是一个单元素,也可以是一个子表。求表尾GetTail(L)02非空广义表除去表头元素以外其它元素所构成的表。表尾一定是一个表。练习A=()
GetHead和GetTail均无定义A=(a,b)
GetHead(A)=aGetTail(A)=(b)
A=(a)
GetHead(A)=aGetTail(A)=()
A=((a))
GetHead(A)=(a)GetTail(A)=()
GetHead(GetTail(GetHead(GetTail(GetTail(A)))))
A=(a,b,(c,d),(e,(f,g)))
d有次序性有长度有深度可递归可共享一个直接前驱和一个直接后继=表中元素个数=表中括号的重数自己可以作为自己的子表可以为其他广义表所共享广义表的特点E=(a,E)=(a,(a,E))=(a,(a,(a,…….))),E为递归表1)A=()2)B=(e)3)C=(a,(b,c,d))4)D=(A,B,C)5)E=(a,E)n=0,因为A是空表n=1,表中元素e是原子n=2,a为原子,(b,c,d)为子表n=3,3个元素都是子表n=2,a为原子,E为子表D=(A,B,C)=((),(e),(a,(b,c,d))),共享表练习:求下列广义表的长度目录导航4.14.24.34.44.54.64.7串案例引入串的类型定义、存储结构及运算数组广义表案例分析与实现LeetCode算法练习题Contents医学研究者最近发现了某些新病毒,通过对这些病毒的分析,得知它们的DNA序列都是环状的。现在研究者收集了大量的病毒DNA和人的DNA数据,想快速检测出这些人是否感染了相应的病毒。为方便研究,研究者将人的DNA和病毒的DNA均表示成由一些小写字母组成的字符串,然后检测某种病毒的DNA序列是否在患者的DNA序列中出现过,如果出现过,则此人感染了病毒,否则没有感染。注意:人的DNA序列是线性的,而病毒的DNA序列是环状的。任务描述对于每组数据输出一行,若患者感染了病毒输出“YES”,否则输出“NO”。输入输出多组数据,每组数据有一行,为序列A和B,A对应病毒的DNA序列,B对应人的DNA序列。A和B都为“0”时输入结束。案例实现--病毒感染检测案例实现--网络入侵检测随着互联网的飞速发展,网络安全问题日益严重。入侵检测技术是一种积极主动防御的安全保障技术,而Snort是其中基于规则匹配的一种入侵检测技术。Snort自1998年被发明以来,历经数年的迭代更新,Snort已成为一个具有多平台(Multi-Platform)、实时(Real-Time)流量分析、网络IP数据包(Pocket)记录等特性的强大的网络入侵检测/防御系统(NetworkIntrusionDetection/PreventionSystem),即NIDS/NIPS。Snort首先需要使用者根据入侵行为的特征,按照一定的规范将这些特征编写成规则,最后通过检测网络数据与规则数据库中的规则是否匹配来判断入侵与否。在Snort入侵检测系统中,规则的匹配效率是影响Snort检测效率的关键。而规则匹配的核心技术是模式匹配算法。请实现一个模式匹配算法,用于网络入侵行为的检测。若检在网络日志中检测到任何一条检测规则中的ip地址,则输出“Networkintrusiondetected.”,反之输出“Nothingdetected.”任务描述输出一行,若检在网络日志中检测到任何一条检测规则中的ip地址,则输出“Networkintrusiondetected.”,反之输出“Nothingdetected.”。输入输出输入共n+m+1行,第1行两个整数n,m(n,m≤100)2~n+1行每行为一条检测规则。规则的格式为:protocol:网络协议ip:ip地址msg:"附加信息"n+2~n+m+1行共m行,为网络日志内容。案例实现--网络入侵检测目录导航4.14.24.34.44.54.64.7串案例引入串的类型定义、存储结构及运算数组广义表案例分析与实现LeetCode算法练习题Contents【算法练习题4.1】LeetCode125验证回文串【问题描述】【输入输出示例】给定一个字符串s,判断其是否为回文串,若是,返回true,否则返回false。其中,回文串是指将字符串中所有大写字母转换为小写字母,并移除所有非字母数字字符之后,正读和反读相同的字符串。字母和数字都属于字母数字字符。输入:"Aman,aplan,acanal:Panama"输出:true解释:"amanaplanacanalpanama"是回文串。【算法练习题4.1】LeetCode125验证回文串【问题分析】【算法练习题4.1】LeetCode125验证回文串【算法步骤】①定义left和right两个指针,初始时left指向第一个字符,right指向最后一个字符。②遍历字符串s,当left<right时,循环执行以下操作:若left所指字符为非字母数字字符,则将其向右移动一步,并循环执行此操作,直到left所指字符为字母或数字字符;若right所指字符为非字母数字字符,则将其向左移动一步,并循环执行此操作,直到right所指字符为字母数字字符;若left和right所指字符转换为小写后不同,则返回false;若left和right所指字符转换为小写后相同,则left向右移动一步,right向左移动一步。③left>=right,遍历完字符串s,返回true。【算法练习题4.1】LeetCode125验证回文串【算法描述】【算法练习题4.1】LeetCode125验证回文串【算法分析】最坏情况下,需遍历字符串s的每个字符,时间复杂度为O(n);只需要两个指针的额外空间,空间复杂度为O(1)。【算法练习题4.2】LeetCode566重塑矩阵【问题描述】【输入输出示例】MATLAB中有一个非常有用的函数reshape(),该函数可以将一个m×n的矩阵重塑为一个r×c的新矩阵,且仍保留原始数据。给定一个由二维数组mat表示的m×n矩阵,以及两个正整数r和c,分别表示重塑矩阵的行数和列数。重塑矩阵时需要将原矩阵的所有元素以相同的行遍历顺序填充。如果给定参数的reshape操作是可行且合理的,则输出新的重塑矩阵;否则输出原矩阵。输入:mat=[[1,2],[3,4]],r=1,c=4输出:[[1,2,3,4]]【算法练习题4.2】LeetCode566重塑矩阵【问题分析】判断给定参数的reshape操作是否可行且合理。若不合理,说明无法进行重塑,直接返回原始矩阵mat。若合理,则可以直接从二维矩阵mat得到r行c列的重塑矩阵。若reshape操作可行,可以将二维数组mat映射为一个一维数组,可以直接将元素mat[x/n,x%n]直接赋值给重塑矩阵ans[x/c,x%c],最后返回重塑矩阵ans即可。【算法练习题4.2】LeetCode566重塑矩阵【算法步骤】①初始化,得到原矩阵的行数和列数。②若m×n和r×c不相等,则直接返回原矩阵。③若m×n和r×c相等,首先对重塑矩阵进行初始化,然后对于任意的x∈[0,m×n),循环执行以下操作:将元素mat[x/n,x%n]赋值给重塑矩阵ans[x/c,x%c]。④返回重塑矩阵ans。【算法练习题4.2】LeetCode566重塑矩阵【算法描述】【算法练习题4.2】LeetCode566重塑矩阵【算法分析】在重塑矩阵成功的前提下,时间复杂度为O(rc),否则直接返回原矩阵,时间复杂度为O(1);不需要额外空间,空间复杂度为O(1)。【算法练习题4.3】LeetCode3无重复字符的最长子串【问题描述】【输入输出示例】给定一个字符串s,请找出其中不含有重复字符的最长子串的长度。输入:s="abcabcbb"输出:3解释:因为无重复字符的最长子串是"abc",所以其长度为3。【算法练习题4.3】LeetCode3无重复字符的最长子串【问题分析】【算法练习题4.3】LeetCode3无重复字符的最长子串【问题分析】【算法练习题4.3】LeetCode3无重复字符的最长子串【问题分析】【算法练习题4.3】LeetCode3无重复字符的最长子串【问题分析】【算法练习题4.3】LeetCode3无重复字符的最长子串
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年数控加工中心项目发展计划
- 14穷人 教学设计-2024-2025学年六年级上册语文统编版
- 8 蝴蝶的家教学设计-2024-2025学年四年级上册语文统编版
- 2024年春八年级生物下册 第七单元 第一章 第四节 鸟的生殖和发育教学实录 (新版)新人教版
- 9 y w(教学设计)-2024-2025学年统编版语文一年级上册
- 2024年秋七年级英语上册 Unit 9 My favorite subject is science Section A教学实录 (新版)人教新目标版
- 2025年电动助力转向装置合作协议书
- 2024-2025学年高中历史 专题一 古代中国的政治家 二 盛唐伟业的奠基人-唐太宗教学教学实录 人民版选修4
- 2024年四年级英语上册 Unit 2 My schoolbag The fourth period(第四课时)教学实录 人教PEP
- 2024年五年级数学下册 七 包装盒-长方体和正方体 信息窗三 体积、容积及其单位间的换算第1课时教学实录 青岛版六三制
- 集装箱知识培训课件
- 江苏省苏州市(2024年-2025年小学六年级语文)部编版小升初真题(下学期)试卷及答案
- 2024年四川泸州古蔺县选调事业单位工作人员26人历年管理单位遴选500模拟题附带答案详解
- 《动静脉采血技术》课件
- 2024年支气管哮喘临床诊疗指南:课件精讲
- 2024版福州存量房买卖合同2篇
- 模具费支付合同模板
- 餐饮部总监述职报告
- 辽宁省沈阳市第七中学2024-2025学年九年级上学期期中英语试题
- 小学金融普及
- 2024电力建设工程绿色建造评价规范
评论
0/150
提交评论