第四章学习小结
第四章
串、数组和广义表总结
1. 串 String
定义:主要是有零个或多个字符组成的有限序列。
存储结构:顺序存储和链式存储,但是串一般使用顺序存储结构。
顺序存储结构
typedef struct { char *ch; //若为非空串,则按串长分配存储区,否则ch为null int length; //串长度 }HString;
链式存储结构:
链式存储结构:
#define CHUNKSIZE 80; //可有用户定义的块大小 typedef struct Chunk{ char ch[CHUNKSIZE ]; struck Chunk *next; }Chunk; typedef struct { Chunk *head,*tail;//串的头尾指针 int curlen; //串的当前长度 }LString;
int Indext(SString S,SString T,int pos){ int i=pos,j=1; //i指向主串,j指向子串 while(S[0]>=i && j<=T[0]){ if(S[i] == T[j]){ ++i; ++j; }else{ i=i-j+2; j=1; } } if(j>T[0]){ return i-T[0]; }else{ return 0; } }
主串长:N ,子串长:M
算法的时间复杂度:
最好的情况下:O(N+M)
最坏的情况下:O(N+M)
3.KMP算法
int Indext_KMP(SString S,SString T,int pos){ //利用模式串T的next函数求T在主串S中第pos个字符之后的位置 //其中,T非空,1<=pos<=Strlength(S) int i=pos,j=1; //i指向主串,j指向子串 while(S[0]>=i && j<=T[0]){ if(j==0 || S[i] == T[j]){ ++i; ++j; }else{ j=next[j]; //模式串向右移动 } } if(j>T[0]){ return i-T[0]; }else{ return 0; } } T的Next函数,算法时间复杂度为O(m) void get_next(SString T,int next[]){ int i = 1; next[1] = 0 ; int j = 0 ; while(i<T[0]){ if(j == 0 || T[i] == T[j]){ ++i; ++j; next[i] = j; }else{ j=next[j]; } } }
修正next算法版本:
void get_nextval(SString T,int nextval[]){ int i = 1; nextval[1] = 0 ; int j = 0 ; while(i<T[0]){ if(j == 0 || T[i] == T[j]){ ++i; ++j; if(T[i] != T[j]){ nextval[i] = j; }else{ nextval[i] = nextval[j]; } }else{ j=nextval[j]; } } }
时间复杂度:O(m+n)
作业实践中的一题:
稀疏矩阵:
首先,定义结构数组,成员有行、列和存储元素。
struct Array { int row; int col; int value; };
由题目矩阵中非零元素的个数<=500,顾定义:
#define MAXLEN 500
然后输入数据:
for (int i = 0; i < N; ++i) { cin >> a[i].row; cin >> a[i].col; cin >> a[i].value; }
最后再遍历数组寻找相应元素:
for (int i = 0; i < MAXLEN; i++)//遍历数组查找目标元素; { if (a[i].value == D) { cout << a[i].row << ' ' << a[i].col << endl; C = 1; break; } } if (C == 0) cout << "ERROR" << endl;
此解题思路简单明了,在查阅相关资料以及询问同学之下进行代码优化,受益匪浅。
上一次的目标是重温上学期的知识并且做好实践三,但是由于时间分配问题,未能如约完成,应当自省。
目标:做好实践三四的选做题,多翻教材回顾知识。
部分资料来源:https://www.jianshu.com/p/ca7ae9a98645