在c++的编程中,字符串匹配问题是十分常见的问题。简单来说,字符串匹配问题就是在文本串中查找特定的模式串的过程。在实际的应用中,字符串匹配算法主要用于文本搜索、图像识别和自然语言处理等领域。本篇文章将着重介绍c++中常用的字符串匹配算法及其实现。
朴素字符串匹配算法朴素字符串匹配算法也被称为暴力搜索匹配算法。其思路就是通过对文本串t的每个位置都依次尝试匹配模式串p,直到找到匹配的位置或者是整个t中不存在p为止。这种算法的时间复杂度较高,为o(n*m),n和m分别是文本串t和模式串p的长度。
c++代码实现如下:
void naive_match(string t, string p) { int n = t.length(); int m = p.length(); for(int i = 0; i <= n-m; i++) { int j; for(j = 0; j < m; j++) { if(t[i+j] != p[j]) break; } if(j == m) { cout << "pattern occurs with shift " << i << endl; } }}
kmp字符串匹配算法kmp字符串匹配算法是一种经典的字符串匹配算法,它的核心思想是通过对模式串p的前缀后缀的最长公共前缀后缀进行匹配,来避免在文本串t中对已经匹配过的字符进行重复匹配的过程。该算法的时间复杂度为o(n),n为文本串的长度。
c++代码实现如下:
void get_next(string p, vector<int>& next) { int m = p.length(); next[0] = -1; int i = 0; int j = -1; while(i < m) { if(j == -1 || p[i] == p[j]) { i++; j++; next[i] = j; } else { j = next[j]; } }}void kmp_match(string t, string p) { int n = t.length(); int m = p.length(); vector<int> next(m+1); get_next(p, next); int i = 0; int j = 0; while(i < n) { if(j == -1 || t[i] == p[j]) { i++; j++; } else { j = next[j]; } if(j == m) { cout << "pattern occurs with shift " << i-m << endl; j = next[j]; } }}
bm字符串匹配算法bm算法是一种基于坏字符和好后缀规则的字符串匹配算法。它的核心思想是通过对模式串p的最后一个字符进行匹配,并通过对文本串t中不匹配的字符进行预处理,来跳过已经匹配过的字符。该算法的时间复杂度为o(n)。
c++代码实现如下:
const int maxchar = 256;void bm_match(string t, string p) { int n = t.length(); int m = p.length(); vector<int> badchar(maxchar, -1); for(int i = 0; i < m; i++) { badchar[int(p[i])] = i; } vector<int> suffix(m+1); vector<bool> prefix(m+1); get_suffix_prefix(p, suffix, prefix); int i = 0; while(i <= n-m) { int j = m-1; while(j >= 0 && p[j] == t[i+j]) j--; if(j < 0) { cout << "pattern occurs with shift " << i << endl; i += (i+m < n) ? m-badchar[int(t[i+m])] : 1; } else { i += max(suffix[j+1], j-badchar[int(t[i+j])]); } }}
本篇文章主要介绍了c++中常用的字符串匹配算法及其实现。朴素字符串匹配算法虽然简单,但时间复杂度较高,kmp和bm算法则能够更快速地找到匹配位置。其中,kmp算法适用于模式串较短,bm算法则适用于模式串较长的情况。在实际的应用中,我们需要根据不同的情况来选择合适的算法来进行字符串匹配。
以上就是c++中的字符串匹配算法及其实现的详细内容。