mirror of
https://github.com/Didnelpsun/CS408.git
synced 2026-11-01 21:07:12 +08:00
更新串
This commit is contained in:
@@ -10,22 +10,25 @@
|
||||
|
||||
串的基本操作是对子串的操作。
|
||||
|
||||
## 顺序串
|
||||
## 串定义
|
||||
|
||||
### 顺序串
|
||||
|
||||
顺序串的结构定义方案
|
||||
|
||||
+ 使用单独的变量length保存串长。
|
||||
+ 使用data[0]记录串长;使得字符位序与数组下标一致;但是由于char类型一个为一字节大小,所以能表示的数字是0到255,太大的串无法表示。
|
||||
+ 没有表示串长的变量,使用\0表示串结尾,对应ASCII码的0号字符。
|
||||
+ data[0]空余,使用单独的变量length保存串长,这个比较常用。
|
||||
+ 使用单独的变量$length$保存串长。
|
||||
+ 使用$data[0]$记录串长;使得字符位序与数组下标一致;但是由于$char$类型一个为一字节大小,所以能表示的数字是$0$到$255$,太大的串无法表示,大于的部分会被截断。
|
||||
+ 没有表示串长的变量,使用$\backslash0$表示串结尾,对应$ASCII$码的$0$号字符。
|
||||
+ $data[0]$空余,使用单独的变量$length$保存串长,这个比较常用。
|
||||
+ 可以定长分配也可以用堆分配。
|
||||
|
||||
## 链串
|
||||
### 链串
|
||||
|
||||
如一般的链式存储结构定义一样,定义一个数据与指向下一位的指针。
|
||||
|
||||
但是如果你只在每个结点定义了一个字节的数据,但是又包含了四个字节的指针,那么存储利用率会很低。
|
||||
|
||||
如果是顺序表数据类型是整数类型,那么这种利用率低的情况确实无可奈何,但是对于串而言,因为一个字节存储一个字符,所以能一个字节存一个字符类型数据,所以为了提升数据存储利用率,可以每个结点存等多个字符。
|
||||
如果是顺序表数据类型是整数类型,那么这种利用率低的情况确实无可奈何,但是对于串而言,因为一个字节存储一个字符,所以能一个字节存一个字符类型数据,所以为了提升数据存储利用率,可以每个结点存等多个字符。这个就是块链串。
|
||||
|
||||
## 模式匹配
|
||||
|
||||
@@ -33,15 +36,15 @@
|
||||
|
||||
### 朴素模式匹配算法
|
||||
|
||||
从主串T、模式串P(子串)的第一个位置开始比较(i=0,j=0),若相等,则 i,j各自+1,然后比较下一个字符。若不等,主串指针回溯到上一轮比较位置的下一个位置,子串回溯到0,再进行下一次比较。令子串长度为m,主串长度为n:
|
||||
从主串$T$、模式串$P$(子串)的第一个位置开始比较($i=0,j=0$),若相等,则$i$,$j$各自$+1$,然后比较下一个字符。若不等,主串指针回溯到上一轮比较位置的下一个位置,子串回溯到$0$,再进行下一次比较。令子串长度为$m$,主串长度为$n$:
|
||||
|
||||
+ 匹配成功的最好时间复杂度:$O(m)$:刚好第一个就匹配上了,总对比次数为子串长度。
|
||||
+ 匹配失败的最好时间复杂度:$O(n-m+1)=O(n-m)=O(n)$:匹配成功之前,每一个与第一个字符都匹配失败。
|
||||
+ 匹配失败的最坏时间复杂度:$O(nm-m^2+m)= O(nm)$:子串除了最后一个对不上,其余的都能对上,则每次遍历完一边后,又要走回头路;直到匹配成功/失败一共需要比较$m\times(n-m+1)$次。m:每次需要移动m次,i需要移动$n-m+1$次。
|
||||
+ 匹配失败的最坏时间复杂度:$O(nm-m^2+m)= O(nm)$:子串除了最后一个对不上,其余的都能对上,则每次遍历完一边后,又要走回头路;直到匹配成功/失败一共需要比较$m\times(n-m+1)$次。$m$:每次需要移动$m$次,$i$需要移动$n-m+1$次。
|
||||
|
||||
### KMP算法
|
||||
|
||||
KMP算法是对朴素模式匹配算法的优化。
|
||||
$KMP$算法是对朴素模式匹配算法的优化。
|
||||
|
||||
朴素模式匹配算法的缺点就是当某些子串与模式串能部分匹配时,主串的扫描指针i经常回溯,从而导致时间开销。
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ $C.88$
|
||||
|
||||
$D.89$
|
||||
|
||||
解:$B$。根据公式$k=2i+j-3$。但是这种公式很难记忆,所以直接找规律。
|
||||
解:$B$。根据公式$k=2i+j-3$。但是这种公式很难记忆,所以直接找规律。观察三对角矩阵不难发现,第一行有两个元素,剩下的在元素$m_{30,30}$所在行之前的$28$行中,每行都有$3$个元素,而$m_{30,30}$之前仅有一个元素$m_{30,29}$,不难发现元素$m_{30,30}$在数组$N$中的下标是$2+28\times3+2-1=87$。
|
||||
|
||||
**例题** 若将$n$阶上三角矩阵$A$按列优先级压缩存放在一维数组$B[1\cdots n(n+1)/2+1]$中,则存放到$B[k]$中的非零元素$a_{i,j}($1\leqslant i,j\leqslant n$)的下标$i$、$j$与$k$的对应关系是()。
|
||||
|
||||
@@ -24,6 +24,8 @@ $C.j(j-1)/2+i$
|
||||
|
||||
$D.j(j-1)/2+i-1$
|
||||
|
||||
解:$C$。按列优先存储,故元素$a$,前面有$j-1$列,共有$1+2+3+\cdots+j-1=j(j-1)/2$个元素,元素$a_{i,j}$在第$j$列上是第$i$个元素,数组$B$的下标是从$1$开始,因此$k=j(j-1)/2+i$。
|
||||
|
||||
**例题** 若将$n$阶下三角矩阵$A$按列优先顺序压缩存放在一维数组$B[1\cdots n(n+1)/2+1]$中,则存放到$B[k]$中的非零元素$a_{i,j}$($1\leqslant i,j\leqslant n$)的下标$i,j$与$k$的对应关系是()。
|
||||
|
||||
$A.(j-1)(2n-j+1)/2+i-j$
|
||||
@@ -34,6 +36,8 @@ $C.(j-1)(2n-j+2)/2+i-j$
|
||||
|
||||
$D.(j-1)(2n-j+1)/2+i-j-1$
|
||||
|
||||
解:$B$。按列优先存储,故元素$a_{i,j}$之前有$j-1$列,共有$n+(n-1)+\cdots+(n-j+2)=(j-1)(2n-j+2)/2$个元素,元素$a_{i,j}$是第$j$列上第$i-j+1$个元素,数组$B$下标从$1$开始,$k=(j-1)(2n-j+2)/2+i-j+1$。
|
||||
|
||||
**例题** 设有一个$12\times12$的对称矩阵$M$,将其上三角部分的元素$m_{i,j}$($1\leqslant i\leqslant j\leqslant12$)按行优先存入$C$语言的一维数组$N$中,元素$m_{7,2}$在$N$中的下标是()。
|
||||
|
||||
$A.50$
|
||||
@@ -43,3 +47,5 @@ $B.51$
|
||||
$C.55$
|
||||
|
||||
$D.66$
|
||||
|
||||
解:$A$。在$C$语言中,数组$N$的下标从$0$开始。第一个元素$m_{1,1}$对应存入$n_0$,矩阵$M$的第一行有$12$个元素,第二行有$11$个,第三行有$10$个,第四行有$9$个,第五行有$8$个,所以$m_{6,6}$。是第$12+11+10+9+8+1=51$个元素,下标应为$50$。
|
||||
|
||||
Reference in New Issue
Block a user