導航:首頁 > 源碼編譯 > 演算法圖解的代碼

演算法圖解的代碼

發布時間:2022-11-20 10:02:53

1. 兩道編程演算法題(兩圖一道),題目如下,可以給出演算法思路或者源代碼,源代碼最好是C語言的

就會個第一題(因為第一題上已經給出了大致思路)

思路:用map容器(它的內部數據結構是一顆紅黑樹,查找和插入數據速度非常快)
map<int,st>a;//key(int):設置為1~n的數;value(st):設置為key的前驅和後繼;

這樣一來就可以像鏈錶快速插入數據,又可以像數組隨機訪問元素(key,就相當於數組的下標)

下面是代碼和運行截圖;

看代碼前建議先了解一下map容器的具體用法;

#include<iostream>

#include<map>

#include<vector>

using namespace std;

struct st{//兩個成員變數用來儲存前驅和後繼

int left;//0

int right;//1

st()

{

left=0;

right=0;

}

};

void input(map<int,st> &a)//輸出

{

st t;

int s=0;

map<int,st>::iterator it;//迭代器(指針)

for(it=a.begin();it!=a.end();it++)//循環迭代

{

t=it->second;

if(t.left==0)//左邊等於0,說明該數是第一個數

{

s=it->first;//記錄key

break;

}

}

t=a[s];

cout<<s<<" ";

while(t.right!=0)//循環找當前數的右邊的數(右邊的為0,就說明該數是最後一個數)

{

cout<<t.right<<" ";

t=a[t.right];

}

}

int main()

{

st t,t_i,t_x,t_k,s;

map<int,st>a;

map<int,st>::iterator it;

int n,x,p,x_l,x_r;

cin>>n;

for(int i=1;i<=n;i++)//map容器賦初值(i,t)

//i:(key)下標;t:(value)結構體變數

{

a.insert(make_pair(i,t));

}

for(int i=2;i<=n;i++)

{

cin>>x>>p;

if(p==0)//x的左邊插入i

{

t=a[x];

if(t.left==0)//x的左邊沒有數

{

t_x.left=i;

t_i.right=x;

a[x]=t_x;

a[i]=t_i;

}

else//x的左邊有數

{

int x_left;

t_x=a[x];

x_left=t_x.left;

t_k=a[x_left];

t_i.right=x;

t_i.left=t_x.left;

t_k.right=i;

t_x.left=i;

a[x]=t_x;

a[i]=t_i;

a[x_left]=t_k;

}

}

else//x的右邊插入i

{

t=a[x];

if(t.right==0)//x的右邊沒有數

{

t_x.right=i;

t_i.left=x;

a[x]=t_x;

a[i]=t_i;

}

else//x的左邊有數

{

int x_right;

t_x=a[x];

x_right=t_x.right;

t_k=a[x_right];

t_i.left=x;

t_i.right=t_x.right;

t_k.left=i;

t_x.right=i;

a[x]=t_x;

a[i]=t_i;

a[x_right]=t_k;

}

}

}

for(it=a.begin();it!=a.end();it++)//循環迭代列印各個數之間的關系

{

cout<<it->first<<" ";

cout<<"左邊:";

cout<<it->second.left<<" ";

cout<<"右邊:";

cout<<it->second.right<<endl;

}

input(a);//列印序列

return 0;

}

/*

4

1 0

2 1

1 0

2 3 4 1

*/

2. 演算法圖解 pdf 高清版

像小說集一樣趣味的演算法新手入門書。
演算法是解決困難的一步步步驟,都是電子信息科學行業的關鍵主題。現如今程序員*常見的演算法早已歷經了古人的探索、檢測及證實。假如你要搞明白這種演算法,又不願困在在繁雜的證實中,這書更是你的不二選擇。這部圖例豐富多彩、扣人心弦的好用手冊將給你輕輕鬆鬆懂得怎樣在自身的程序流程中高效率應用關鍵的演算法。
這書範例豐富多彩,圖片配文字,以令人非常容易了解的方法詮釋了演算法,致力於協助程序員在平時新項目中充分發揮演算法的動能。書中的前三章將協助你奠定基礎,陪你學習培訓二分查找、大O表示法、二種基礎的數據結構及其遞歸等。剩下的篇數將關鍵詳細介紹運用普遍的演算法,主要內容包含:應對實際難題時的處理方法,例如,什麼時候選用貪欲演算法或動態規劃;散列表的運用;圖演算法;Kzui近鄰演算法。

目錄
前言
致謝
關於本書
第1章 演算法簡介1
1.1引言1
1.1.1性能方面1
1.1.2問題解決技巧2
1.2二分查找2
1.2.1更佳的查找方式4
1.2.2運行時間8
1.3大O 表示法8
1.3.1演算法的運行時間以不同的速度增加9
1.3.2理解不同的大O運行時間10
1.3.3大O 表示法指出了最糟情況下的運行時間12
1.3.4一些常見的大O運行時間12
1.3.5旅行商13
1.4小結15
第2章 選擇排序16
2.1內存的工作原理16
2.2數組和鏈表18
2.2.1鏈表19
2.2.2數組20
2.2.3術語21
2.2.4在中間插入22
2.2.5刪除23
2.3選擇排序25
2.4小結28
第3章 遞歸29
3.1遞歸29
3.2基線條件和遞歸條件32
3.3棧33
3.3.1調用棧34
3.3.2遞歸調用棧36
3.4小結40
第4章 快速排序41
4.1分而治之41
4.2快速排序47
4.3再談大O表示法52
4.3.1比較合並排序和快速排序53
4.3.2平均情況和最糟情況54
4.4小結57
第5章 散列表58
5.1散列函數60
5.2應用案例63
5.2.1將散列表用於查找63
5.2.2防止重復64
5.2.3將散列表用作緩存66
5.2.4小結68
5.3沖突69
5.4性能71
5.4.1填裝因子72
5.4.2良好的散列函數74
5.5小結75
第6章 廣度優先搜索76
6.1圖簡介77
6.2圖是什麼79
6.3廣度優先搜索79
6.3.1查找最短路徑82
6.3.2隊列83
6.4實現圖84
6.5實現演算法86
6.6小結93
第7章 狄克斯特拉演算法94
7.1使用狄克斯特拉演算法95
7.2術語98
7.3換鋼琴100
7.4負權邊105
7.5實現108
7.6小結116
第8章 貪婪演算法117
8.1教室調度問題117
8.2背包問題119
8.3集合覆蓋問題121
8.4NP 完全問題127
8.4.1旅行商問題詳解127
8.4.2如何識別NP 完全問題131
8.5小結133
第9章 動態規劃134
9.1背包問題134
9.1.1簡單演算法135
9.1.2動態規劃136
9.2背包問題FAQ143
9.2.1再增加一件商品將如何呢143
9.2.2行的排列順序發生變化時結果將如何145
9.2.3可以逐列而不是逐行填充網格嗎146
9.2.4增加一件更小的商品將如何呢146
9.2.5可以偷商品的一部分嗎146
9.2.6旅遊行程最優化147
9.2.7處理相互依賴的情況148
9.2.8計算最終的解時會涉及兩個以上的子背包嗎148
9.2.9最優解可能導致背包沒裝滿嗎149
9.3最長公共子串149
9.3.1繪制網格150
9.3.2填充網格151
9.3.3揭曉答案152
9.3.4最長公共子序列153
9.3.5最長公共子序列之解決方案154
9.4小結155
第10章 K 最近鄰演算法156
10.1橙子還是柚子156
10.2創建推薦系統158
10.2.1特徵抽取159
10.2.2回歸162
10.2.3挑選合適的特徵164
10.3機器學習簡介165
10.3.1OCR165
10.3.2創建垃圾郵件過濾器166
10.3.3預測股票市場167
10.4小結167
第11章 接下來如何做168
11.1樹168
11.2反向索引171
11.3傅里葉變換171
11.4並行演算法172
11.5MapRece173
11.5.1分布式演算法為何很有用173
11.5.2映射函數173
11.5.3歸並函數174
11.6布隆過濾器和HyperLogLog174
11.6.1布隆過濾器175
11.6.2HyperLogLog176
11.7SHA 演算法176
11.7.1比較文件177
11.7.2檢查密碼178
11.8局部敏感的散列演算法178
11.9Diffie-Hellman 密鑰交換179
11.10線性規劃180
11.11結語180
練習答案181

自取: https://url80.ctfile.com/f/32319880-518802548-9892a0
(訪問密碼:3284)

3. 如何理解《演算法圖解》中的快速排序演算法

快速排序的基本思想就是從一個數組中任意挑選一個元素(通常來說會選擇最左邊的元素)作為中軸元素,將剩下的元素以中軸元素作為比較的標准,將小於等於中軸元素的放到中軸元素的左邊,將大於中軸元素的放到中軸元素的右邊。

然後以當前中軸元素的位置為界,將左半部分子數組和右半部分子數組看成兩個新的數組,重復上述操作,直到子數組的元素個數小於等於1(因為一個元素的數組必定是有序的)。

以下的代碼中會常常使用交換數組中兩個元素值的Swap方法,其代碼如下

publicstaticvoidSwap(int[] A, inti, intj){

inttmp;

tmp = A[i];

A[i] = A[j];

A[j] = tmp;


(3)演算法圖解的代碼擴展閱讀:

快速排序演算法 的基本思想是:將所要進行排序的數分為左右兩個部分,其中一部分的所有數據都比另外一 部分的數據小,然後將所分得的兩部分數據進行同樣的劃分,重復執行以上的劃分操作,直 到所有要進行排序的數據變為有序為止。

定義兩個變數low和high,將low、high分別設置為要進行排序的序列的起始元素和最後一個元素的下標。第一次,low和high的取值分別為0和n-1,接下來的每次取值由劃分得到的序列起始元素和最後一個元素的下標來決定。

定義一個變數key,接下來以key的取值為基準將數組A劃分為左右兩個部分,通 常,key值為要進行排序序列的第一個元素值。第一次的取值為A[0],以後毎次取值由要劃 分序列的起始元素決定。

從high所指向的數組元素開始向左掃描,掃描的同時將下標為high的數組元素依次與劃分基準值key進行比較操作,直到high不大於low或找到第一個小於基準值key的數組元素,然後將該值賦值給low所指向的數組元素,同時將low右移一個位置。

如果low依然小於high,那麼由low所指向的數組元素開始向右掃描,掃描的同時將下標為low的數組元素值依次與劃分的基準值key進行比較操作,直到low不小於high或找到第一個大於基準值key的數組元素,然後將該值賦給high所指向的數組元素,同時將high左移一個位置。

重復步驟(3) (4),直到low的植不小於high為止,這時成功劃分後得到的左右兩部分分別為A[low……pos-1]和A[pos+1……high],其中,pos下標所對應的數組元素的值就是進行劃分的基準值key,所以在劃分結束時還要將下標為pos的數組元素賦值 為 key。

4. 求圖割演算法 graph cut 的matlab代碼

解決方案1:
直接用緝鼎光刮叱鈣癸水含驚ifft();例如信號x
y=fft(x);%對信號傅里葉變換到頻域
z=ifft(y);%對信號y傅里葉反變換到時域,

解決方案2:
工具箱啊。IFFT()函數

5. 《演算法圖解》pdf

本書示例豐富,圖文並茂,以讓人容易理解的方式闡釋了演算法,旨在幫助程序員在日常項目中更好地發揮演算法的能量。書中的前三章將幫助你打下基礎,帶你學習二分查找、大O表示法、兩種基本的數據結構以及遞歸等。餘下的篇幅將主要介紹應用廣泛的演算法,具體內容包括:面對具體問題時的解決技巧,比如,何時採用貪婪演算法或動態規劃;散列表的應用;圖演算法;Kzui近鄰演算法。

目錄
前言
致謝
關於本書
第1章 演算法簡介1
1.1引言1
1.1.1性能方面1
1.1.2問題解決技巧2
1.2二分查找2
1.2.1更佳的查找方式4
1.2.2運行時間8
1.3大O 表示法8
1.3.1演算法的運行時間以不同的速度增加9
1.3.2理解不同的大O運行時間10
1.3.3大O 表示法指出了最糟情況下的運行時間12
1.3.4一些常見的大O運行時間12
1.3.5旅行商13
1.4小結15
第2章 選擇排序16
2.1內存的工作原理16
2.2數組和鏈表18
2.2.1鏈表19
2.2.2數組20
2.2.3術語21
2.2.4在中間插入22
2.2.5刪除23
2.3選擇排序25
2.4小結28
第3章 遞歸29
3.1遞歸29
3.2基線條件和遞歸條件32
3.3棧33
3.3.1調用棧34
3.3.2遞歸調用棧36
3.4小結40
第4章 快速排序41
4.1分而治之41
4.2快速排序47
4.3再談大O表示法52
4.3.1比較合並排序和快速排序53
4.3.2平均情況和最糟情況54
4.4小結57
第5章 散列表58
5.1散列函數60
5.2應用案例63
5.2.1將散列表用於查找63
5.2.2防止重復64
5.2.3將散列表用作緩存66
5.2.4小結68
5.3沖突69
5.4性能71
5.4.1填裝因子72
5.4.2良好的散列函數74
5.5小結75
第6章 廣度優先搜索76
6.1圖簡介77
6.2圖是什麼79
6.3廣度優先搜索79
6.3.1查找最短路徑82
6.3.2隊列83
6.4實現圖84
6.5實現演算法86
6.6小結93
第7章 狄克斯特拉演算法94
7.1使用狄克斯特拉演算法95
7.2術語98
7.3換鋼琴100
7.4負權邊105
7.5實現108
7.6小結116
第8章 貪婪演算法117
8.1教室調度問題117
8.2背包問題119
8.3集合覆蓋問題121
8.4NP 完全問題127
8.4.1旅行商問題詳解127
8.4.2如何識別NP 完全問題131
8.5小結133
第9章 動態規劃134
9.1背包問題134
9.1.1簡單演算法135
9.1.2動態規劃136
9.2背包問題FAQ143
9.2.1再增加一件商品將如何呢143
9.2.2行的排列順序發生變化時結果將如何145
9.2.3可以逐列而不是逐行填充網格嗎146
9.2.4增加一件更小的商品將如何呢146
9.2.5可以偷商品的一部分嗎146
9.2.6旅遊行程最優化147
9.2.7處理相互依賴的情況148
9.2.8計算最終的解時會涉及兩個以上的子背包嗎148
9.2.9最優解可能導致背包沒裝滿嗎149
9.3最長公共子串149
9.3.1繪制網格150
9.3.2填充網格151
9.3.3揭曉答案152
9.3.4最長公共子序列153
9.3.5最長公共子序列之解決方案154
9.4小結155
第10章 K 最近鄰演算法156
10.1橙子還是柚子156
10.2創建推薦系統158
10.2.1特徵抽取159
10.2.2回歸162
10.2.3挑選合適的特徵164
10.3機器學習簡介165
10.3.1OCR165
10.3.2創建垃圾郵件過濾器166
10.3.3預測股票市場167
10.4小結167
第11章 接下來如何做168
11.1樹168
11.2反向索引171
11.3傅里葉變換171
11.4並行演算法172
11.5MapRece173
11.5.1分布式演算法為何很有用173
11.5.2映射函數173
11.5.3歸並函數174
11.6布隆過濾器和HyperLogLog174
11.6.1布隆過濾器175
11.6.2HyperLogLog176
11.7SHA 演算法176
11.7.1比較文件177
11.7.2檢查密碼178
11.8局部敏感的散列演算法178
11.9Diffie-Hellman 密鑰交換179
11.10線性規劃180
11.11結語180
練習答案181

最後,這里為大家准備了幾百本的互聯網電子書,有需要的過來取吧。 點擊獲取

6. KMP演算法詳細代碼

KMP.java

源代碼為:

package algorithm.kmp;

/**
* KMP演算法的Java實現例子與測試、分析
* @author 崔衛兵
* @date 2009-3-25
*/
public class KMP {
/**
* 對子串加以預處理,從而找到匹配失敗時子串回退的位置
* 找到匹配失敗時的最合適的回退位置,而不是回退到子串的第一個字元,即可提高查找的效率
* 因此為了找到這個合適的位置,先對子串預處理,從而得到一個回退位置的數組
* @param B,待查找子串的char數組
* @return
*/
public static int[] preProcess(char [] B) {
int size = B.length;
int[] P = new int[size];
P[0]=0;
int j=0;
//每循環一次,就會找到一個回退位置
for(int i=1;i<size;i++){
//當找到第一個匹配的字元時,即j>0時才會執行這個循環
//或者說p2中的j++會在p1之前執行(限於第一次執行的條件下)
//p1
while(j>0 && B[j]!=B[i]){
j=P[j];
}
//p2,由此可以看出,只有當子串中含有重復字元時,回退的位置才會被優化
if(B[j]==B[i]){
j++;
}
//找到一個回退位置j,把其放入P[i]中
P[i]=j;
}
return P;
}

/**
* KMP實現
* @param parStr
* @param subStr
* @return
*/
public static void kmp(String parStr, String subStr) {
int subSize = subStr.length();
int parSize = parStr.length();
char[] B = subStr.toCharArray();
char[] A = parStr.toCharArray();
int[] P = preProcess(B);
int j=0;
int k =0;
for(int i=0;i<parSize;i++){
//當找到第一個匹配的字元時,即j>0時才會執行這個循環
//或者說p2中的j++會在p1之前執行(限於第一次執行的條件下)
//p1
while(j>0 && B[j]!=A[i]){
//找到合適的回退位置
j=P[j-1];
}
//p2 找到一個匹配的字元
if(B[j]==A[i]){
j++;
}
//輸出匹配結果,並且讓比較繼續下去
if(j==subSize){
j=P[j-1];
k++;
System.out.printf("Find subString '%s' at %d\n",subStr,i-subSize+1);
}
}
System.out.printf("Totally found %d times for '%s'.\n\n",k,subStr);
}

public static void main(String[] args) {
//回退位置數組為P[0, 0, 0, 0, 0, 0]
kmp("abcdeg, abcdeh, abcdef!這個會匹配1次","abcdef");
//回退位置數組為P[0, 0, 1, 2, 3, 4]
kmp("Test ititi ititit! Test ititit!這個會匹配2次","ititit");
//回退位置數組為P[0, 0, 0]
kmp("測試漢字的匹配,崔衛兵。這個會匹配1次","崔衛兵");
//回退位置數組為P[0, 0, 0, 1, 2, 3, 4, 5, 6]
kmp("這個會匹配0次","it1it1it1");
}
}

7. 圖解查找演算法之插值查找(帶源碼

在前面我們了解了二分查找,就是把一個集合的元素一分為二,用中間值和目標查找值相比較,直到要查找的值和中間值相等,則表示查找成功,反之表示不成功。為什麼這里會再次提到二分查找呢?事實上,插值查找是二分查找的升級版。

用一個很簡單的例子就可以把插值查找解釋的很清楚。在字典裡面找」boy」這個單詞時,我們肯定不會從第一頁開始找,而是從首字母為b的位置開始查找,然後再找到第二個字母在字母表中的位置,找到對應的位置後,重復這個過程,這樣就可以快速的找到目標單詞。

接下來就介紹一下插值查找吧。

我們知道的的二分查找有一個必要的前提,必須是有序的數組才可以進行二分查找,同樣插值查找也只能用於一個呈線性增長的有序數組中。

首先我們在數組中找到左邊索引low和右邊的索引high,目標查找值key

在二分查找中mid表示數組的中間值,而插值查找中mid表示一個自適應處,插值查找每次是從自適應mid處開始查找,mid的計算方式為:low + (key – arr[low]) / (arr[high] – arr[low]) * (high - low);在這里mid表示的就是目標值key在序列總的所佔比。

源碼:

int func(int arr[], int len, int key)

{

      int low,high,mid;

      low = 0;

      high = len-1;

  int h = (key-arr[low])/(arr[high]-arr[low]);

      while(low <= high)

      {

          mid = h * (high - low);

          if(key < arr[mid])

          {

              high = mid - 1;

          }

          else if(key > arr[mid])

          {

            low = mid + 1;

          }

          else

          {

              return mid;

          }

      }

    return -1;

  }

8. 數獨 演算法 C語言 代碼

當年我們做大程的時候本來也想做數獨來著,後來時間不夠沒做成.不知道專業人士怎麼編的,只能提供一點當時的思路給你,
1.9*9個格子對應一個數組A,數組的第一個值從0到9表示其中填的數字,0就是不填,另一個值表示它在桌面上的位置就是坐標
2.需要10張圖片,空白和9個數字
3.通過對滑鼠點擊的反應改變格子數組A的值,且將相應圖片覆蓋在相應坐標上
4.事先輸入若干組數組A的值(每組81個數),作為題庫
5.進行游戲時隨機抽取題庫中的一組,再隨機抽取若干格子顯示出來,其他留白.
6.填完後用三個循環判斷下每行每列每塊是否有相同的數字,沒有則通過.
具體編按鈕、放圖、滑鼠點擊響應等各種問題查一下書,有很多書上有很多教的這種一小段一小段的程序源代碼,直接抄下就行了。
加油^^

9. 二分查找演算法實現(圖解)與實例

當我們要從一個序列中查找一個元素的時候,二分查找是一種非常快速的查找演算法,二分查找又叫折半查找。

它對要查找的序列有兩個要求,一是該序列必須是有序的(即該序列中的所有元素都是按照大小關系排好序的,升序和降序都可以,本文假設是升序排列的),二是該序列必須是順序存儲的。

如果一個序列是無序的或者是鏈表,那麼該序列就不能進行二分查找。之所以被查找的序列要滿足這樣的條件,是由二分查找演算法的原理決定的。

二分查找又稱折半查找,優點是比較次數少,查找速度快,平均性能好;其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查找方法適用於不經常變動而查找頻繁的有序列表。

二分查找能應用於任何類型的數據,只要能將這些數據按照某種規則進行排序。然而,正因為它依賴於一個有序的集合,這使得它在處理那些頻繁插入和刪除操作的數據集時不太高效。這是因為,對於插入和操作來說,為了保證查找過程正常進行,必須保證數據集始終有序。相對於查找來說,維護一個有序數據集的代價更高。此外,元素必須存儲在連續的空間中。因此,當待搜索的集合是相對靜態的數據集時,此時使用二分查找是最好的選擇。

二分查找演算法的原理如下:

二分查找之所以快速,是因為它在匹配不成功的時候,每次都能排除剩餘元素中一半的元素。因此可能包含目標元素的有效范圍就收縮得很快,而不像順序查找那樣,每次僅能排除一個元素。

二分查找法實質上是不斷地將有序數據集進行對半分割,並檢查每個分區的中間元素。

此實現過程的實施是通過變數left和right控制一個循環來查找元素(其中left和right是正在查找的數據集的兩個邊界值)。

二分查找的時間復雜度取決於查找過程中分區數可能的最大值。對於一個有n個元素的數據集來說,最多可以進行O(㏒₂n)次分區。對於二分查找,這表示最終可能在最壞的情況下執行的檢查的次數:例如,在沒有找到目標時。所以二分查找的時間復雜度為O(㏒₂n)。

參考:
https://www.html.cn/qa/other/23018.html

https://www.cnblogs.com/idreamo/p/9000762.html

10. 圖解KMP字元串匹配演算法

kmp演算法跟之前講的bm演算法思想有一定的相似性。之前提到過,bm演算法中有個好後綴的概念,而在kmp中有個好前綴的概念,什麼是好前綴,我們先來看下面這個例子。

觀察上面這個例子,已經匹配的abcde稱為好前綴,a與之後的bcde都不匹配,所以沒有必要再比一次,直接滑動到e之後即可。
  那如果前綴中有互相匹配的字元呢?

觀察上面這個例子,這個時候如果我們直接滑到好前綴之後,則會過度滑動,錯失匹配子串。那我們如何根據好前綴來進行合理滑動?

  其實就是看當前的好前綴的前綴和後綴是否有匹配的,找到最長匹配長度,直接滑動。鑒於不止一次找最長匹配長度,我們完全可以先初始化一個數組,保存在當前好前綴情況下,最長匹配長度是多少,這時候我們的next數組就出來了。

  我們定義一個next數組,表示在當前好前綴下,好前綴的前綴和後綴的最長匹配子串長度,這個最長匹配長度表示這個子串之前已經匹配過匹配了,不需要再次進行匹配,直接從子串的下一個字元開始匹配。

 我們是否每次算next[i]時都需要每一個字元進行匹配,是否可以根據next[i - 1]進行推導以便減少不必要的比較。
  帶著這個思路我們來看看下面的步驟:
  假設next[i - 1] = k - 1;
  如果modelStr[k] = modelStr[i] 則next[i]=k

如果modelStr[k] != modelStr[i],我們是否可以直接認定next[i] = next[i - 1]?

通過上面這個例子,我們可以很清晰地看到,next[i]!=next[i-1],那當modelStr[k]!=modelStr[i]時候,我們已知next[0],next[1]…next[i-1],如何推導出next[i]呢?
  假設modelStr[x…i]是前綴後綴能匹配的最長後綴子串,那麼最長匹配前綴子串為modelStr[0…i-x]

我們在求這個最長匹配串的時候,他的前面的次長匹配串(不包含當前i的),也就是modelStr[x…i-1]在之前應該是已經求解出來了的,因此我們只需要找到這個某一個已經求解的匹配串,假設前綴子串為modelStr[0…i-x-1],後綴子串為modelStr[x…i-1],且modelStr[i-x] == modelStr[i],這個前綴後綴子串即為次前綴子串,加上當前字元即為最長匹配前綴後綴子串。
代碼實現
  首先在kmp演算法中最主要的next數組,這個數組標志著截止到當前下標的最長前綴後綴匹配子串字元個數,kmp演算法裡面,如果某個前綴是好前綴,即與模式串前綴匹配,我們就可以利用一定的技巧不止向前滑動一個字元,具體看前面的講解。我們提前不知道哪些是好前綴,並且匹配過程不止一次,因此我們在最開始調用一個初始化方法,初始化next數組。
  1.如果上一個字元的最長前綴子串的下一個字元==當前字元,上一個字元的最長前綴子串直接加上當前字元即可
  2.如果不等於,需要找到之前存在的最長前綴子串的下一個字元等於當前子串的,然後設置當前字元子串的最長前綴後綴子串

然後開始利用next數組進行匹配,從第一個字元開始匹配進行匹配,找到第一個不匹配的字元,這時候之前的都是匹配的,接下來先判斷是否已經是完全匹配,是直接返回,不是,判斷是否第一個就不匹配,是直接往後面匹配。如果有好前綴,這時候就利用到了next數組,通過next數組知道當前可以從哪個開始匹配,之前的都不用進行匹配。

閱讀全文

與演算法圖解的代碼相關的資料

熱點內容
編譯原理如何運用到編程中 瀏覽:14
linux選擇資料庫 瀏覽:375
php兩個數組差集 瀏覽:978
迷你pdf閱讀器下載 瀏覽:432
做一個python小程序 瀏覽:654
pythonossystem和 瀏覽:644
win2008如何搭建ftp伺服器 瀏覽:53
安卓手機為什麼不翻牌 瀏覽:545
刪除pkpm及相關文件夾 瀏覽:480
房貸解壓銀行內部流程 瀏覽:734
安卓手機如何更改語音 瀏覽:599
android紅包實現 瀏覽:733
蘋果的nvme為什麼安卓不用 瀏覽:31
python輸入單詞統計個數 瀏覽:997
腳本軟體提取源碼 瀏覽:281
程序員能給自己的微信錢包刷錢么 瀏覽:72
怎麼讓小天才app查看寶貝的通訊錄 瀏覽:623
dxgpdf 瀏覽:257
哪個命令 瀏覽:51
文件不能打包壓縮 瀏覽:708