Algoritmo de análise de caso - algoritmo de correspondência de padrão de string
Vi um blog de alta qualidade na Internet para compartilhar com vocês. Reproduzido do conhecido blogueiro "Little Grey Ape" , se quiser, apoie o original.
Link original
Hoje, compartilharei com vocês um algoritmo de correspondência de padrões sobre comparação de strings.Entre as operações relacionadas em strings na estrutura de dados, a operação de posicionamento em substrings é geralmente chamada de correspondência de padrões de string e também é a mais importante em vários processamentos de strings. Uma das operações importantes, e a substring também é chamada de string de padrão. Existem principalmente dois algoritmos de correspondência comumente usados para a string principal e a string de padrão: o algoritmo ingênuo de correspondência de padrões e o algoritmo KMP (algoritmo de correspondência de padrões aprimorado). Analise esses dois algoritmos separadamente.
1. Algoritmo de correspondência de padrões ingênuo
O algoritmo ingênuo de correspondência de padrões também é conhecido como algoritmo Brute-Fuchs. Sua ideia básica é comparar o primeiro caractere da string principal com o primeiro caractere da string padrão. Os caracteres são comparados, caso contrário, o segundo caractere da string principal é novamente comparado com o primeiro caractere da string de padrão, até que cada caractere na string de padrão corresponda à sequência de caracteres consecutivos na string principal. Se a correspondência for bem-sucedida, se o conteúdo que corresponde à sequência de padrão não puder ser encontrado na sequência principal, isso é chamado de falha de correspondência.
A seguir, dê um exemplo de armazenamento de strings em matrizes de caracteres para implementar um algoritmo simples de correspondência de padrões.
//传入主串s和模式串t,同时设定从主串中开始匹配的位置pos
int index(char s[],char t[],int pos) {
int i,j,slen,tlen;
i = pos;
j = 0;
slen = s.length; //获取到主串的长度
tlen = t.length; //获取到模式串的长度
while (i<slen && j<tlen) {
if (s[i] == t[j]) {
i++;
j++;
}
else {
i = i-j+1;
j=0;
}
}
if (j>=tlen) {
return i-tlen;
}
return 1;
}
2. Algoritmo KMP (algoritmo de correspondência de padrões aprimorado)
O algoritmo KMP é uma melhoria do algoritmo anterior. Comparado com o algoritmo ingênuo de correspondência de padrões, o algoritmo KMP não precisa voltar sempre que os caracteres comparados não forem iguais no processo de correspondência da string principal e da string de padrão. O ponteiro de posição do caractere da string principal, em vez de usar o resultado de "correspondência parcial" que foi obtido, "deslize" a string do padrão para a direita o máximo possível antes de continuar a comparar.
Suponha que a string de padrão seja "P0 ... P (m-1)", a ideia do algoritmo de correspondência KMP é: quando o caractere Pj na string de padrão não é igual ao caractere correspondente Si na string principal, porque os primeiros j caracteres ("P0 … P (j-1) ”) foi correspondido com sucesso, então, se“ P0… P (k-1) ”na string de padrão for o mesmo que“ P (jk)… P (j-1) ”, então P0 pode ser comparado com Si, de forma que i não precise retroceder.
No algoritmo KMP, o deslizamento da substring pode ser alcançado de acordo com o próximo valor da função da string padrão. Se next [j] = k, então next [j] significa quando o Pj na string padrão não é igual ao caractere correspondente na string principal , Compare o Pnext [j] da string padrão com os caracteres correspondentes da string principal,
A definição da próxima função é a seguinte:
A seguir está o procedimento para encontrar a próxima função da string de padrão:
//求模式串p的next函数值,并存入数组next中
void Get_next(char *p,int next[])
{
int i,j,slen;
slen = strlen(p); //获取到模式串的长度
i=0;
while (i<slen) {
if (j==-1||p[i]==p[j]) {
++i;
++j;
next[i] = j;
} else {
j = next[j];
}
}
}
Depois de obter a próxima função,
No algoritmo de correspondência de padrão KMP, se o subscrito do primeiro caractere da string de padrão for 0, o algoritmo KMP será o seguinte:
/*利用模式串p的next函数,求p在主串s中从第pos个字符开始的位置*/
/*若匹配成功,返回模式串在主串的位置下标,否则返回-1 */
int Index_KMP(char *s,char *p,int pos,int next[])
{
int i,j,slen,plen;
i=pos-1;
j=-1;
slen = strlen(s); //求主串的长度
plen = strlen(p); //求模式串的长度
while (i<slen && j<plen) {
if (j==-1||s[i]==p[j]) {
++i;
++j;
} else {
j=next[j];
}
}
if (j>=plen) {
return i-plen;
}
else {
return -1
}
}
Vou compartilhar o algoritmo de correspondência de padrões de string aqui. Se houver alguma deficiência, espero que todos possam me corrigir. |
---|
Por favor, apoie o original