Algoritmo de coincidencia de patrones KMP mejorado --- matriz nextval

Se recomienda revisar primero un algoritmo KMP

Defectos del algoritmo de coincidencia de patrones KMP

Inserte la descripción de la imagen aquí
Se puede encontrar aquí que el paso 2345 es en realidad un juicio redundante. Dado que los caracteres en la posición 2345 en la cadena T son iguales a la primera a, el valor del primer siguiente [1] se puede usar para reemplazar los caracteres siguientes que son igual a 1 El valor de next [j], por lo que necesitamos mejorar la siguiente función; llamamos a la siguiente matriz mejorada nextval

Encuentra la matriz nextval

#include<iostream>
using namespace std;
//nextval数组
void get_nextval(string T,int* nextval)
{
    
    
	int i = -1; //指向前缀
	int j = 0; //指向后缀
	nextval[0] = -1;
	while (j < (T.length())-1)
	{
    
    
		if (i == -1 || T[i] == T[j])
		{
    
    
			i++;
			j++;
            //如果前缀字符与后缀字符不同
			if (T[i] != T[j])
			{
    
    
				//当前nextval[j]的值等于i位置的值
				nextval[j] = i;
			}
			else 
			{
    
    
				//如果前缀字符与后缀字符相同,则将前缀字符的nextval值赋值给后缀字符的nextval值
				nextval[j] = nextval[i];
			}

		}
		else 
		{
    
    
			i= nextval[i];
		}
	}
}
void test()
{
    
    
	//测试nextval数组-----------------
	string T = "ababaaaba";
	int nextval[9] = {
    
    };
	get_nextval(T, nextval);
	for (int i = 0; i < 9; i++)
	{
    
    
		cout << nextval[i] << "  ";
	}
}
int main()
{
    
    
	test();
	system("pause");
	return 0;
}

Inserte la descripción de la imagen aquí

Código de mejora de KMP:

Inserte la descripción de la imagen aquí

#include<iostream>
using namespace std;
//nextval数组
void get_nextval(string T,int* nextval)
{
    
    
	int i = -1; //指向前缀
	int j = 0; //指向后缀
	nextval[0] = -1;
	while (j < (T.length())-1)
	{
    
    
		if (i == -1 || T[i] == T[j])
		{
    
    
			i++;
			j++;
            //如果前缀字符与后缀字符不同
			if (T[i] != T[j])
			{
    
    
				//当前nextval[j]的值等于i位置的值
				nextval[j] = i;
			}
			else 
			{
    
    
				//如果前缀字符与后缀字符相同,则将前缀字符的nextval值赋值给后缀字符的nextval值
				nextval[j] = nextval[i]+1;
			}

		}
		else 
		{
    
    
			i= nextval[i];
		}
	}
}
//改进KMP改进
int test(string S,string T,int* nextval)
{
    
    
	int i =0;//指向主串S
	int j = 0; //指向子串T
	while (i <= S.length() - 1 && j <= T.length() - 1)
	{
    
    
		if (j == 0 || S[i] == T[j])
		{
    
    
			i++;
			j++;
		}
		else 
		{
    
    
			j = nextval[j];
		}
	}
	cout << "i=" << i << endl;
	cout << "j=" << j << endl;
	if (j == T.length())
	{
    
    
		return i - j;
	}
	return -1;
}
void test()
{
    
    
	string S = "aaaabaaaaaxcdef";
	string T = "aaaaax";
	int nextval[6] = {
    
    };
	get_nextval(T, nextval);
	int ret=test(S, T, nextval);
	cout << "子串T在主串S中的起始位置为:"<<ret << endl;
}
int main()
{
    
    
	test();
	system("pause");
	return 0;
}

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/m0_53157173/article/details/114729322
Recomendado
Clasificación