This chapter is even more watery. The first half is a review of Happy chapter in my heart. kmp is a bit dead.
1 Array Addressing
Define a[9][8][7], a[1][2][3] as the number of elements in the array
This is a better understanding from a python perspective, where the python output from a three-dimensional array is (possibly nonstandard)
[ [ 0 1 2 3 4 5 6 7 8 9 0 1] [ 0 1 2 3 4 5 6 7 8 9 0 1] [ 0 1 2 3 4 5 6 7 8 9 0 1] ]
That is, three-dimensional is just a stack of two-dimensional objects, so
&a[1][2][3] = &a[0][0][0] + sizeof(type) * 1 * 8 * 7 + 2 * 7 + 3
2 Matrix
2.1 Special Matrix Compression
Diagonal matrix: A one-dimensional array stored on the main diagonal line is sufficient.
Triangle Matrix: Tear up/down triangles into one-dimensional arrays by rows.
Symmetric matrix: stored as upper triangle.
2.2 Sparse Matrix and Triple Table
It means that when a matrix is very large, but only individual elements are non-zero elements, only non-zero elements can be stored, either in groups or in chains.
Triple table: In each case, the non-zero element is stored in rows, columns, and values. Stored by row first.
Triple tables are very effective for transposed matrices, but if you need to work with all the elements of a column (for example, all the elements in the second column + 5), you need to traverse the entire table with a triple table, you need to use a cross-linked table.
Cross-linked list: Each row and column has a row header and a column header. Then each row and column is a circular chain table, such as P52 in a book. This allows one row/column to be traversed through the table header.
2.3 String
Before kmp, look for yourself. It's very simple.
Important: Do not go online and pick kmp's tutorials freely, because the results of different tutorial failure functions may be different. If you fill in the blanks at the end of the term, the results from other tutorials may be wrong. Check out the books more, the failure functions in the books are the least understood way of failure functions. The corresponding algorithms below also change with the way failure functions are defined.
2.3.1 Failure Function
void fail(string s) { int len=s.length(); int i=0; Next[0]=-1; //Assume the current letter is m and the previous letter is n for(int j=1;j<len;j++){ //Traverse all letters to get a failure function i=Next[j-1]; //What is the Number of Next s to find the last letter n of this letter m while(s[j]!=s[i+1]&&i>=0) i=Next[i]; //Keep Next looking for the next n if m //The following if&else is classical in determining how the last while loop ended if(s[j]==s[i+1]) Next[j]=i+1; //If so, that's right else Next[j]=-1; //Always wrong, that's NEW } }
This certainly won't make you fully understand, so I'm going to lift chestnuts now
(is a string, spaces are easy to watch)
-
The failure function of abcf abcf abcf is:
-1 -1 -1 -1 0 1 2 3 4 5 6 7
This is not intended to be understood through code, primarily to understand how the failure function operates in a simple way, but it often leads to an incorrect understanding: the first consecutive element from scratch is the same as the current element and the number is consecutive. -
The failure function of abcf abcd abcf is
-1 -1 -1 -1 0 1 2 -1 0 1 2 3
As we can see here, -1 occurs when the characters don't match, but the numbers here are also continuous, that is, an incremental sequence of + 1 each time starting at -1. -
abcf abcd abcf abcf when the last f is judged, the previous failure function is as follows:
-1 -1 -1 -1 0 1 2 -1 0 1 2 3 4 5 6
How do we determine the failure function of the last character,'f', when we start reading it? For easy viewing, I paste the code below.
i=Next[j-1]; // i=Next[14] = 6 Finds the last letter c of the f letter first, and the EXT of c is 6 while(s[j]!=s[i+1]&&i>=0) i=Next[i]; // s[15]=f ≠ s[7]=d i=Next[6] = 2 // s[15]=f =s[3]=f Jump out of the loop //It is worth noting that if you start with a sentence i=j-1=14, change the first sentence to the first i=Next[i] //Here i was initially assigned 14, 6, 2, and the letters in all three places are c //And Next[14]=6, Next[6]=2, that is, compare 7 and 3 with 15 to see if they are the same if(s[j]==s[i+1]) Next[j]=i+1; //Since you jumped out of while by s[j]==s[i+1], take this if, Next[15]=3
2.3.2 KMP algorithm
int kmp(string s, string p){ // s is the parent string and p is the child string int len_s = s.length(); int len_p = p.length(); int i = 0, j = 0; // i is the pointer to the parent string and j is the pointer to the child string while (i < len_s && j < len_p){ if (s[i] == p[j]){ // Current location matched successfully i++; j++; // Pointer moves one bit backward if(j==len_p) return i-len_p; //End of Match, Return to Match Location } else{ //Substring first matches fail, find parent next letter matches if(j==0) i++; //String non-first match failed, find next Next Next of Next of the previous Next of the letter else j=Next[j-1]+1; } } return -1; }
For the string abcf abcd abcf abcf, the failure function is
-1 -1 -1 -1 0 1 2 -1 0 1 2 3 4 5 6 3
The current 14-bit matches are successful. When the 15th-bit f matches fail, look for the 14th-bit ext, j=Next[14]=6; query with the 7th letter d_f, continues to fail with the matching j=Next[6]=2; query with the 3rd letter F matches successfully and moves to i++&j+.
There are three loops in the above process: first match failure j=Next[14]=6, second match failure j=Next[6]=2, third match success i++&j+.
2.3.3 Supplement
For this kind of kmp in books, I can say as much as I can, and the process I understood at that time is also here. If I still don't understand it, I will find more data and manually code it again and again to understand it.