接着昨天的選擇排序和冒泡排序之后,今天來實現一下順序查找和蠻力字符串匹配兩個算法。
順序查找就是將給定的查找鍵和列表周玲的每個元素進行比較,直到找到一個匹配成功的元素返回該元素下標,查找成功,或者查找整個列表二沒有匹配元素,查找失敗。這里記錄一下限位器版順序查找方法。限位器就是指將查找鍵添加到列表最后,這樣在查找的過程中,不用再每次都判斷是否到達列表尾部來判斷查找是否失敗,而是在查找結束后,判斷匹配元素下標是否小於n(假設列表有n個元素)來判斷查找是否成功。下面是限位器版順序查找算法:
限位器版順序查找算法: SequentialSearch(A[0....n], K) //輸入:一個n個元素的數組A和一個查找鍵K //輸出:第一個值等於K的元素的位置,如果找不到這樣的元素,返回-1 A[n]<—K while A[i]≠K do i++ if i<n return i; else return -1; //這個算法是《算法設計與分析》上的,我認為這里的else沒有必要,當查找成功時已經提前返回主函數, //不會再執行return -1,在代碼實現的過程中,嘗試了去掉else,運行結果也是正確的 |
上面這種算法的時間復雜度是:Θ(n)
下面是該算法的C++實現代碼:
#include <iostream> using namespace std; typedef char Elemtype; int SequentialSearch(Elemtype ESearch[], int n, Elemtype K); void main(){ Elemtype a[6] = {'a','r','j','l','h'};//定義的數組長度要比原表大1,預留出K的位置 Elemtype K; cin >> K; getchar(); int iLocation = SequentialSearch(a, 5, K);//這里傳遞的是列表下標的最大值 if (iLocation == -1){ cout << "查找失敗,列表中沒有"<<K<<"元素"; } else cout << "查找成功,該元素位置為:" << iLocation; getchar(); } int SequentialSearch(Elemtype ESearch[], int n,Elemtype K){ ESearch[n] = K; int i = 0; while (ESearch[i] != K){ i++; } if (i < n){ return i; } return -1; }
下面介紹一下蠻力字符串匹配。
該算法的做法是將模式(也就是較短的子串,長度為m)對准文本(也就是較長的字符串,長度為n)的前m個字符,從左到右匹配每一對相應的字符,如果有m對字符都匹配成功,那么算法停止,或者當遇到有一對不匹配時就將模式向右移一位,然后繼續從模式的第一個字符與文本進行匹配。在這個過程中,當文本剩余字符的長度小於模式時算法就可以停止了,因為后面的都不可能再匹配成功,因此,文本的下標達到n-m時終止。下面是蠻力字符串匹配的算法:
蠻力匹配字符串算法: BruteForceStringMatch(T[0....n-1],P[0...m-1]) //輸入:一個n個字符的數組T[0...n-1]代表一段文本,一個m個字符的數組P[0...m-1]代表一個模式 //輸出:匹配成功時返回文本中第一個匹配子串的第一個字符的位置,失敗時返回-1 for i<—0 to n-m do j <—0 while T[i+j] = P[j] and j < m do j++ if j=m return i return -1 |
該算法的時間復雜度在最壞的情況下也就是每次模式匹配都進行到最后一對字符時匹配失敗,也就是要進行m次比較,這樣就要進行n-m+1次這樣的匹配,該算法屬於Θ(nm),書上描述的在查找隨機文本時,顯示出的是線性效率Θ(n+m)=Θ(n)。下面是該算法的C++實現代碼:
#include <iostream> using namespace std; typedef char Elemtype; int BruteForceStringMatch(Elemtype T[], int n, Elemtype P[], int m); int main(){ Elemtype T[10] = { 'a', 'p', 'p', 'l', 'e', 's' }; Elemtype P[3] = { 'p', 'p','l' }; Elemtype Ps[2] = { 'p', 's' }; int result1 = BruteForceStringMatch(T, 10, P, 3); if (result1 == -1){ cout << "T和P的匹配失敗"; } else cout << "T和P匹配成功,P在T中的字符起始位置為:" << result1; getchar(); return 1; } int BruteForceStringMatch(Elemtype T[], int n, Elemtype P[], int m){ int i = 0,j=0; for (i = 0; i < n - m; i++){ j = 0; while (j < m && T[i + j] == P[j]){ j++; } if (j == m){ return i; } } return -1; }