Algoritmo do Matching
algoritmo Brute Force
BF algoritmo, também conhecido como algoritmo de correspondência de padrão simples foi proposto por Bruce Força para o algoritmo idéia básica é simples e comparação bruto de um problema. C implementação do algoritmo de código é simples, mas encontrou alguns problemas em operação detalhes.
problemas com o código
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define LEN 100
int B_FIndex(char S[],char T[])
{
int i = 0,j = 0;
int Len_S = strlen(S); // 使用strlen函数获取字符串长度
int Len_T = strlen(T);
if(S == NULL || T == NULL || Len_S < Len_T) // Error Input
return -1;
while(i < Len_S && j < Len_T)
{
if(S[i] == T[j])
{
i++;
j++;
}// end if
else
{
i = i - j +1;
j = 0;
}// end else
}//end while
if(j >=Len_T)
{
printf("Success patterened at %d",i-j); // 匹配成功位置信息提示
return 0;
}
else
{
printf("Fail patterened");
return -1;
}
}//end BF
int main(int argc,char * argv[])
{
char S[LEN+1],T[LEN+1];
fgets(S,sizeof(S),stdin); // 采用推荐的安全函数fgets
fgets(T,sizeof(T),stdin);
B_FIndex(S,T);
}
Este código primeira vista não há problema, e não houve diferença em outro código blog, o compilador pode ser passado, mas ele não pode corresponder 100% correto, por que você diz?
case1: = subsequência serial mestre
hello world
hello world
Success patterened at 0
Process returned 0 (0x0) execution time : 16.536 s
Press any key to continue.
Você pode corrigir as expectativas de saída.
Caso 2: substring <string principal
hello world
hello
Fail patterened
Process returned 0 (0x0) execution time : 9.249 s
Press any key to continue.
Isto é o que faz com que?
Porque scanf () função só pode receber uma cadeia contínua, então o final dos espaços de encontro, ter um impacto sobre a função correspondente, então eu escolhi os fgets () função (relação () recebe função é mais seguro, universal).
Se mudar para dirigir gets () função em uma aplicação típica não é problema, o código acima funciona corretamente. Mas gets () função maior problema é que ele não verifica se a entrada exceder o comprimento da matriz, o que faz com que estouro de memória questões de segurança.
A verdadeira razão causando o problema em outra diferença com os fgets () e recebe () é:
- gets () lê os caracteres um a um, leia a quebra de linha guia é parada (descarte de nova linha)
- fgets () é temporizado para o carácter, até encontrar a primeira linha de ruptura ou sido lidos para o sizeof (str) -1 caracteres no final da operação. Se uma nova linha é lido, ele vai economizar com quebras de linha e outros caracteres .
Portanto, a questão-chave é o caractere de nova linha.
No caso do case1, a cadeia de caracteres principal
h | e | eu | eu | o | W | o | r | eu | d | '\ N' | '\ 0' |
---|
Também para cordas
h | e | eu | eu | o | W | o | r | eu | d | '\ N' | '\ 0' |
---|
Assim, o jogo é bem sucedido, não há problema.
Mas, em caso2, como uma string
h | e | eu | eu | o | '\ N' | '\ 0' |
---|
Assim fazendo com que o substring correspondente é tomar o tempo para ir ao jogo de nova linha.
Quando a análise acima é o problema, a solução é para calcular o comprimento da cadeia de caracteres na linha direita BF função de alimentação perdido, o código da chave é modificado como se segue
int Len_S = strlen(S) - 1; // 使用strlen函数获取字符串长度,不包含结束符,
int Len_T = strlen(T) - 1; // 减1就去掉了换行符。
Claro, existem outras maneiras, só para colocar emendas específicas para a frente a este problema.
algoritmo KMP
Sobre este algoritmo não está aqui, o código c ++ dado diretamente
próxima função
método dá aqui dois tipos de função seguinte, o trabalho pode
/* 求模式全的netx[]函数
next[]下标从0开始,初始值定位-1
S:cdbcbabcdbcdbcacabc
T:bcdbcdbca
*/
#include <iostream>
#include <string>
using namespace std;
int get_next1(string T,int next[])
{
next[0] = -1;
int k = -1;
for (int i = 1; i < T.size(); i++)
{
while (k > -1 && T[k + 1] != T[i])///如果匹配到某一个不相等的时候,开始回溯
{
k = next[k];///回到next数组中记录的位置重新匹配
}
if (T[k + 1] == T[i] || k == -1)///如果字符一样,继续向前匹配
{
k++;
}
next[i] = k;///将最大匹配的值赋给next数组
}
}
int get_next2(string T,int next[])
{// 求next函数的值,
int i = 0;
signed int j = -1;
next[0] = -1; // initialization
while(i < T.size()) // 与T[0]字符的ASCII值比较,显然始终成立
{
if(j == -1 || T[i] == T[j])
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
int main(int argc,char* argv[])
{
string T;
cout << "Please input Substring: ";
cin >> T;
int next[T.size()] = {0};
get_next1(T,next);
cout << "The next[] of substring T:";
for(int i =0; i <T.size(); i++)
cout << next[i] << " ";
cout << endl;
get_next2(T,next);
cout << "The next[] of substring T:";
for(int i =0; i <T.size(); i++)
cout << next[i] << " ";
cout << endl;
}
exportação
Please input Substring: bcdbcdbca
The get_next1 of substring T:-1 0 0 0 1 2 3 4 0
The get_next2 of substring T:-1 0 0 0 1 2 3 4 5
Process returned 0 (0x0) execution time : 4.611 s
Press any key to continue.
KMP alcançar
#include <iostream>
#include <cstring>
using namespace std;
/*
得到next数组
*/
void get_next(string T, int *next)
{
int j, k;
j = 0;
k = -1;
next[0] = -1;
while(j <T.size())
{
if(k == -1 || T[j] == T[k])
{
j++;
k++;
next[j] = k;
}
else
{
k = next[k];
}
}
}
/*
KMP算法
*/
int KMP(string S, string T, int *next)
{
int i = 0, j = 0;
get_next(T, next);
int Len_S = S.size();
int Len_T = T.size();
while (i < Len_S && j < Len_T)
{
if (j == -1 || S[i] == T[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j == Len_T)
{
cout << "Success patterned with shift " << i-j <<endl;
return i - j;
}
else
{
cout << "Fail patterned" << endl;
return -1;
}
}
int main()
{
string S,T;
cin >> S ;
cin >> T;
int next[T.size()];
int i;
Get_Next(T, next);
cout << "模式串的next的值为:";
for (i = 0; i < T.size(); i++)
cout << next[i] << " ";
cout << endl;
KMP(S, T, next);
}
exportação
cdbcbabcdbcdbcacabc
bcdbcdbca
模式串的next的值为:-1 0 0 0 1 2 3 4 5
Success patterned with shift 6
Process returned 0 (0x0) execution time : 19.706 s
Press any key to continue.