弦
文字列(または文字列)は、ゼロ以上の文字のシーケンスによって制限されています。
文字列の格納構造
図1に示すように、固定長の順次記憶:
#define MAXLEN 255
typedef struct{
char ch[MAXLEN+1];
int length;
}SString;
2、サーモパイル型順次記憶:
typedef struct{
char *ch; //若是非空串,则按串长分配存储区
int length; //串的当前长度
}HString;
3、チェーンストア(通常は行います)。
#define CHUNKSIZE 80
typedef struct Chunk{
char ch[CHUNKSIZE];
struct Chunk *next;
}Chunk;
typedef struct{
Chunk *head,*tail;
int length;
}LString;
文字列のパターンマッチングアルゴリズム
BF(Brute_Force)アルゴリズム
アルゴリズムのステップ:
1、それぞれ、使用技術はjは初期値1であり、i及びjはメインストリングSを示し、T現在ペンディングモードキャラクタ比較位置、IのPOS初期値ポインタ
二つの文字列の場合は、2文字列の末尾への比較ない、すなわち、i及びjは、以下SとTの長さに等しいよりもサイクル動作である:
(1)S.ch [i]とT.ch [J]比較、等しい場合、iおよびj文字列内の次の位置を示し、比較は、後続文字続け
、など再始動マッチへのポインタバック、ビーズからの次の文字(iはI-J + 2 =た場合(2) )と、再び第1パターン文字列から比較文字
3、jは> T.length、Tは、次に一致が成功し、そしてTは、メインの最初の文字に等しい文字パターンを返し、連続等しい文字のシーケンスでターンと主ストリングSの各文字のモードを説明している場合数値列S(iT.length)、そうでない場合は失敗し、ゼロを返します
要約:開始POSヘッド一致から一つ一つが成功したとして暴力は、マッチングアルゴリズムです。
コードの実装。
int Index_BF(SString S, SString T, int pos){
int i = pos, j = 1;
while (i <= S.length && j <= T.length){
if (S.ch[i] == T.ch[j]){
++i;
++j;
}
else{
i = i - j + 2;
j = 1;
}
}
if (j > T.length)return i - T.length;
else return 0;
}
(これは、コードを貼り付け、この子はそれあまりにも......(Wulian)で死亡したマークダウン)
時間計算量解析:
最良のケース(1)、片道失敗した試合は、最初の文字列と、メインモードで行われました対応する文字列の比較。
主ストリング長がn、文字列照合を想定長さmのサブストリングは、i番目のメインストリングI-1 + Mのモードの開始位置、比較の合計数(成功+失敗)のための主要な文字列成功マッチから成功していないと仮定、N-M + 1によってその初期位置、成功確率に一致するこれらの位置を想定する1は比較の平均数に等しい(N + M)/ 2のための最良の一致に成功している
最高の状態で平均時間計算場合O(N + M)。
(2)最悪の場合、各旅行は比較的失敗した試合は、対応する文字で発生するマスターパターン文字列の最後の文字列です。
Iの総数の比較M、比較の平均数は、(N-M + 2)は、M / 2
Oの平均最悪の場合の時間複雑度(N- M)。
KMPアルゴリズム
改善BFアルゴリズム:トリップが発生するたびに、私は、何のバックポインタを不等文字マッチング処理を比較していないが、結果として「スライディング」パターン文字列の右側にある「部分一致」を用いて得られていますいくつかの距離離れた後、比較し続けます。
必要[]配列、次の[J]に次の意味である:とき、j番目のビットパターン列と、主ビットI「ミスマッチ」の文字列は、私の第一パターン文字列次の[J]ビットは、メインストリングを続行しますビットマッチ。
アルゴリズムの理解:
j番目のビット列とiビットのマスター「ミスマッチ」、メインの文字列を続行するkビットパターン文字列の一致がIビット際にパターン文字列を考えてみましょう、そして条件は、kについて満たすべき位置でメインストリームにおけるk-1要素の前にK-1の要素の前に私は(すなわち、すべての要素の前に)等しくなるようにパターン文字列のk番目のポイントに対応するべきである;そしてパターン文字列は、j個の位置に一致されているので、パターンを満たさなければならないため:K-1、K-1 iは、パターン文字列内のプッシュ、条件kが成立することとなる位置、に等しく、メインストリングのストリングの位置jの前部要素に対応するの前部要素のJ K-1位の前等しい位置に対応するK-1およびK元素の前部要素。
明らかに、すべての文字jの位置の前方に配置された文字列は、Pであり、Jは2つのK-1 P列の前部の長さであることであり、最長プレフィックスとサフィックスが等しいです。
アルゴリズムを理解した後、次のハード定義されていない[j]がある:
J = 1の場合、次の[J] = 1 ;( ない次いで見てみるだけで、最初に等しい)
他のケースを:次の[J] = K、全てのk-1の最初のj個の文字の位置に等しく前接尾語長の最も長いストリング。
達成するためのKMPアルゴリズムコード:
int Index_KMP(SString S, SString T, int pos){
int i = pos, j = 1;
while (i <= S.length && j <= T.length){
if(j==0||S.ch[i]==T.ch[j]){++i;++j} //前面第一位没匹配上或现在匹配成功,就继续向后匹配
else j=next[j];
}
if (j > T.length) return i - T.length;
else return 0;
}
次の配列の値を見つける
利用可能な方法は、再帰:
まず、次の[1] = 0は明らかであろう。
次の[J] = K、以前の分析は、k 1及びk番目の点の位置Jの最初のk個の要素の前に満たすことでした-1に等しい要素に対応するには、今、次の[J + 1]が必要;
2例:
(1)とk番目の要素のj番目の要素は、フロントフロントいずれかを拡張する拡張、および次を前記に対応し、等しいです; [J + 1]は間違いなく、+ 1をk個、すなわち次に[J + 1] =次に[J] + +1等しく
なければならない(2)とk番目の要素のj番目の要素は、j番目の要素と等しくありませんそして、次の[K]のモード列= K「要素コンパレータは、それらが同じである場合、次の[J + 1] = Kを(メインストリングとパターン文字列自体との比として同時にパターン文字列を想像します) 」 + 1、すなわち次の[J + 1] =次の [K] +1;
等しくない場合、再帰が正常に一致するまで継続する、または存在しないK「、次の[J + 1] = 1の条件を満足します 。
コードの実装:
void get_next(SString T,int next[]){
int i=1,j=0;
next[1]=0;
while(i<T.length){
if(j==0||T.ch[i]==T.ch[j]){++i;++j;next[i]=j;}
else j=next[j];
}
}
コードを理解することは少し難しいかもしれませんが、j番目の要素のi番目の要素が等しいとき、次の決定の各段階でのノートの値、コードの後ろには、私を求めて、以前の分析と統合そうれます。
次補正値算出:
直接コードで:
void get_nextval(SString T,int nextval[]){
int i=1,j=0;
nextval[1]=0;
while(i<T.length){
if(j==0||T.ch[i]==T.ch[j]){
++i;++j;
if(T.ch[i]!=T.ch[j])nextval[i]=j;
else nextval[i]=nextval[j];
}
else j=nextval[j];
}
}
次の[j]があり、次の[次の[...次の[J]になりました...];
配列
配列からなる同じタイプの要素の順序集合であります
一次元位置マップ記憶空間のアレイ
n次元配列A [0 ... b1-1,0 ... B2-1、...、0 ... BN-1]データ要素格納場所に計算:LOC(J1、J2、...、JN)= LOC(0、 0、...、0)+(B2 * ... * BN * J1 + B3 * ... * BN * J1 + ... + BN * JN-1 + JN)* L
特殊な圧縮行列
対称行列満たす:AIJ = AJI
N ^ 2つの記憶圧縮要素Nであってもよい(N + 1)/ 2ラインの順番下三角(対角線を含む)、メインプログラムメモリに番目の要素の空間の元;
SAとの対応関係[K]とされ、AIJ
一般的なリスト
プロモーションテーブルは、通常と呼ばれる、線形のテーブルである一般:LS =(A1、A2、 ...)
ここで、nテーブルの長さであり、AIは、単一の要素であってもよいし、テーブルが一般化することができます。
二つの重要な業務全般一覧
(1)ヘッダ取る GetHead():また、サブテーブルであってもよい第一の非取らヘッダ要素は、単一の原子であってもよい一般化テーブルを空にし;
(2)フッタ取る GetTailを():抜き出さテーブル外部テーブルの末尾を除去するために、テーブルの端すなわち残りの要素からなる表は、一般形でなければなりません。
------------------------------------
注:この記事の内容は、「データ構造(C言語からのすべてです第二版)「(ヤン魏分教師A)