多维数组 特殊矩阵 对称矩阵 三对角矩阵
[ a 00 , a 01 , a 10 , a 11 , a 12 , a 13 , a 21 , … , a n − 1 n − 2 , a n − 1 n − 1 ] [a_{00}, a_{01}, a_{10}, a_{11}, a_{12}, a_{13}, a_{21},… ,a_{n-1n-2}, a_{n-1n-1}] [ a 00 , a 01 , a 10 , a 11 , a 12 , a 13 , a 21 , … , a n − 1 n − 2 , a n − 1 n − 1 ]
稀疏矩阵 稀疏因子e:矩阵中有s个非零元素 e = s / ( m ∗ n ) e = s / (m * n) e = s / ( m ∗ n )
每个非零元素有一个三元组唯一确定(row、col、value)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 template <class Type > class SparseMatrix <Type>;template <class Type > class Trituple {friend class SparseMatrix <Type>private : int row, col; Type value; } template <class Type >class SparseMatrix { int Rows, Cols, Terms; Trituple<Type> smArray[MaxTerms]; public : SparseMatrix ( int MaxRow, int Maxcol ); SparseMatrix<Type> Transpose ( ) ; SparseMatrix<Type> Add ( SparseMatrix<Type> b ); SparseMatrix<Type> Multiply ( SparseMatrix<Type> b ); }
快速转置(类似基数排序) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 template <class Type > SparseMatrix<Type>SparseMatrix<Type>::FastTranspos ( ) { int *rowSize = new int [Cols]; int *rowStart = new int [Cols]; SparseMatrix<Type> b ( Cols, Rows ) ; b.Rows = Cols; b.Cols = Rows; b.Terms = Terms; if ( Terms > 0 ) { for (int i = 0 ; i < Cols; i++){ rowSize[i] = 0 ; } for ( i = 0 ; i < Terms; i++ ){ rowSize[smArray[i].col]++; } rowStart[0 ] = 0 ; for ( i = 1 ; i < Cols; i++ ){ rowStart[i] = rowStart[i-1 ]+rowSize[i-1 ]; } for ( i = 0 ; i < Terms; i++ ) { int j = rowStart[smArray[i].col]; b.smArray[j].row = smArray[i].col; b.smArray[j].col = smArray[i].row; b.smArray[j].value = smArray[i].value; rowStart[smArray[i].col]++; } } delete [ ] rowSize; delete [ ] rowStart; return b; }
时间复杂度:O ( m a x ( C o l s , T e r m s ) ) O(max(Cols,Terms)) O ( ma x ( C o l s , T er m s ))
空间复杂度:增加两个体积为Cols的辅助数组
稀疏矩阵的正交链表表示
表头结点(H i H_i H i ):head、next、down、right
非零元素结点:head、row、col、down、value、right
总表头结点:row、col、terms(非零元素个数)
时间复杂度
建立表头结点:O ( m a x { n , m } ) O(max\{n, m\}) O ( ma x { n , m })
链入新结点:O ( 1 ) O(1) O ( 1 )
链入t个非零元结点:O ( m a x ( t , n , m ) ) O(max(t, n, m)) O ( ma x ( t , n , m ))
字符串
n个字符的有限序列
若一个字符串不为空,从这个串中连续取出若干个字符组成的串叫做原串的子串
称子串的第0个字符在串中的位置为子串在串中的位置
空串是任意串的子串
任一串是它自身的子串
除本身外,一个串的其它子串都是他的真子串
模式匹配
在串中寻找子串在串中的位置(子串第一个字符)
子串称为模式P ,串称为目标T
KMP算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 void getNext (int next[]) { int j = 0 , k = -1 , lengthP = curLength; next[0 ] = -1 ; while (j < lengthP){ if ( k == -1 || ch[j] == ch[k]) { j++; k++; next[j] = k; } else { k = next[k]; } } }; int fastFind (String pat) const { int posP = 0 , posT = 0 ; int lengthP = pat.curLen, lengthT = curLen; while ( posP < lengthP && posT < lengthT ){ if ( pat.ch[posP] == ch[posT] || posP = -1 ){ posP++; posT++; } else { posP = pat.next[posP]; } } if ( posP < lengthP ){ return -1 ; } else { return posT-lengthP; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include <iostream> #include <vector> #include <string> using namespace std;vector<int > buildNext (const string &pattern) { int m = pattern.size (); vector<int > next (m) ; next[0 ] = -1 ; int j = 0 ; int k = -1 ; while (j < m - 1 ) { if (k == -1 || pattern[j] == pattern[k]) { j++; k++; next[j] = k; } else { k = next[k]; } } return next; } vector<int > KMP (const string &text, const string &pattern) { vector<int > result; vector<int > next = buildNext (pattern); int i = 0 ; int j = 0 ; int n = text.size (); int m = pattern.size (); while (i < n) { if (j == -1 || text[i] == pattern[j]) { i++; j++; } else { j = next[j]; } if (j == m) { result.push_back (i - j); j = next[j - 1 ]; } } return result; } int main () { string text, pattern; cout << "输入文本: " ; cin >> text; cout << "输入模式: " ; cin >> pattern; vector<int > positions = KMP (text, pattern); cout << "匹配位置: " ; for (int pos : positions) { cout << pos << " " ; } cout << endl; return 0 ; }
getNext():O ( L e n g t h P ) O(LengthP) O ( L e n g t h P )
fastFind():O ( L e n g t h T ) O(LengthT) O ( L e n g t h T )
KMP:O ( L e n g t h P + L e n g t h T ) O(LengthP + LengthT) O ( L e n g t h P + L e n g t h T )
广义表
n个表元素组成的有限序列,记作L S ( a 0 , a 1 , … , a n − 1 ) LS(a_0,a_1,\dots, a_{n-1}) L S ( a 0 , a 1 , … , a n − 1 )
a j a_j a j 可以是表(子表)也可以是数据元素(原子)
n为长度
n=0的广义表是空表
第一个元素为表头(head),除第一个元素外其他所有元素组成的表为表尾(tail)
特性
实现 链表表示
结点定义
utype:结点类型
value:utype为0时value为引用计数
tlink:下一个结点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class GenList ;class GenListNode { friend class Genlist ; private : int utype; union { int ref; int intinfo; char charinfo; GenListNode *hlink; } value; public : GenListNode ( ) : utype (0 ), tlink (NULL ), ref (0 ) { } GenListNode (int t, GenListNode *next = NULL ) { } GenListNode &Info ( ) ; int nodetype ( ) { return utype; } void setInfo (GenListNode & x ) ; }; class GenList { private : GenListNode *first; GenListNode *Copy ( GenListNode *ls ) ; int depth ( GenListNode *ls ) ; int equal (GenListNode *s, GenListNode *t) ; void Remove (GenListNode *ls ) ; public : Genlist ( ); ~GenList ( ); GenListNode Head ( ) ; GenList Tail ( ) ; GenListNode *First ( ) ; GenListNode * Next ( GenListNode *elem ) ; GenList Addon (GenList& list, GenListNode &x) ; void Push ( GenListNode& x ) ; void setNext (GenListNode *elem1, GenListNode *elem2) ; void Copy (const GenList & l) ; int depth ( ) ; int Createlist ( GenListNode *ls, char * s ) ; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void GenList::copy ( const GenList& ls ) { first = copy ( ls.first ); } GenListNode* GenList::copy ( GenListNode * ls ) { GenListNode *q = NULL ; if ( ls != NULL ) { q = new GenListNode ( ls->utype, NULL ); switch ( ls->utype ) { case 0 : q->value.ref = ls->value.ref; break ; case 1 : q->value.intgrinfo = ls->value.intgrinfo; break ; case 2 : q->value.charinfo = ls->value.charinfo; break ; case 3 : q->value.hlink = copy (ls->value.hlink); } q->tlink = copy (ls->tlink); } return q; }