一、本章内容小结:(以PTA作业题为例)
串的存储结构:
1.串的顺序存储结构:用一组地址连续的存储单元来存储串中的字符序列。一般用定长数组为每个定义的串变量分配一个固定长度的存储区。
2.串的链式存储结构:一个结点可以存放一个字符,可以考虑存放多个字符,最后一个结点若是未被占满,可用“#”或其他非串值字符补全。
串和串的模式匹配:
第一次接触到KMP这种如此优化的算法,会有点难理解,需要花的时间会比较长。
BF算法:(以下是用BF算法打的题目,但是最后一个测试点会过不了,主串长度100万,模式长度10万,尾字符不匹配:答案错误。)
1 #include2 using namespace std; 3 4 5 int Index_BF(string S, string T) 6 { 7 int i=0; 8 int j=0; 9 while(i<=(S.length())&&j<=(T.length())) 10 { 11 if( S[i] == T[j] ) 12 { 13 i++; 14 j++; 15 } 16 else 17 { 18 if (j==0) 19 { 20 i++; 21 } 22 else 23 { 24 i = i-j+2; 25 j=0; 26 } 27 } 28 29 } 30 if(j>(T.length())) return i-T.length(); 31 else return 0; 32 } 33 34 int main() 35 { 36 string S; 37 string T; 38 cin >> S; 39 cin >> T; 40 int p = Index_BF(S, T); 41 if (p == 0) cout << "0"; 42 else cout << p; 43 return 0; 44 }
KMP算法:(以下是用KMP算法打的代码)
1 #include2 #include <string> 3 using namespace std; 4 5 int* get_next(string T) //next函数的实现 6 { 7 int i=0, j=-1; 8 int* next = new int[T.size()]; 9 next[0] = -1; 10 while(i<T.length()) 11 { 12 if(j==-1||T[i]==T[j]) 13 { 14 if(T[i+1]==T[j+1]) next[++i] = next[++j]; 15 else next[++i]=++j; 16 } 17 else j = next[j]; 18 } 19 return next; 20 } 21 22 int Index_KMP(string S, string T) 23 { 24 int i=0, j=1; 25 int n = S.length(); 26 int m = T.length(); 27 int* next = get_next(T); 28 while(i<=n&&j<=m) 29 { 30 if(j==0||S[i]==T[j]) 31 { 32 i++; 33 j++; 34 } 35 else j = next[j]; 36 } 37 if (j>m) 38 return i-m; 39 else 40 return 0; 41 } 42 43 int main() 44 { 45 string S, T; 46 cin >> S; 47 cin >> T; 48 int p = Index_KMP(S, T); 49 cout << p; 50 return 0; 51 }
数组:
- 数组的逻辑结构:数组可以看作线性表的推广。数组作为一种数据结构其特点是结构中的元素本身可以是具有某种结构的数据,但属于同一数据类型,所以,n 维数组可以看作是线性表的一种扩展。
- 数组的存储:
按元素的下标求m×n二维数组中某个数据元素 aij地址的计算:
①行优先:LOC(aij) = LOC(a00) + ( i*n + j ) * s
②列优先:LOC(aij) = LOC(a00) + ( i*m + j ) * s
其中,LOC(i,j) : aij 在内存中的地址;LOC(0,0) : a00 存储的地址,其实就是整个二维数组存放的起始地址。
- 特殊矩阵的压缩存储:
如果矩阵中有很多数值相同的数据元素,在存储时,可以考虑对其进行适当的压缩存储。
有必要压缩存储的矩阵大致分为两大类:
①矩阵中含有大量的相同数值,称为特殊矩阵(例如对称矩阵和上下三角矩阵)。
②矩阵中只有极少量的元素是非 0 元素,称为稀疏矩阵(三元组顺序表、行逻辑连接的顺序表、十字链表)。
两类矩阵压缩存储的方法:
①特殊矩阵中,对于相同的数据元素,只存储一个。
②稀疏矩阵中,只需要存储非 0 元素。
*稀疏矩阵的三种不同的存储方法,采用哪种方法要看程序具体要实现的功能:
--如果想完成例如矩阵的转置这样的操作,宜采用三元组顺序表;
--如果想实现矩阵的乘法这样的功能,宜采用行逻辑链接的顺序表;
--如果矩阵运算过程中(例如矩阵的加法),需要不断地插入非 0 元素或删除变为 0 的元素,宜采用十字链表法。
PTA实践题代码(使用数组)
1 #include2 #include 3 using namespace std; 4 5 int main() 6 { 7 int a[100001], b[100001], c[200002]; 8 int n, m, count=0; 9 int i=0, j=0; 10 cin >> n >> m; 11 for (int i=0;i > a[i]; 12 for (int j=0;j > b[j]; 13 sort(a, a+n); 14 sort(b, b+m); 15 for (;i m;) 16 { 17 if (a[i]==b[j]) 18 { 19 c[count++] = a[i]; 20 i++; 21 j++; 22 } 23 else if(a[i]>b[j]) j++; 24 else if(a[i]; 25 } 26 cout << count << endl; 27 for (int i=0;i ) 28 { 29 cout << c[i]; 30 if(i!=count-1) cout << " "; 31 } 32 return 0; 33 }
广义表:广义表是线性表的推广,又称列表。(因为用的比较少就没有很精细的学完)
二、遇到的困难:
在学习KMP算法是比较难以理解,看了好几遍才看明白;以及知识点有点混淆,以至于有点分不清楚char和string,所以只能回头再重温以前的知识点,便于区分。
三、目标:
希望在下一阶段的学习中,可以投入更多时间和精力,更专注一点,提高学习效率,用更短的时间学得更精细,与此同时也要多回头重温学过的知识。