1. 程式人生 > >字串匹配的RabinKarp演算法的c語言實現

字串匹配的RabinKarp演算法的c語言實現

</pre><pre name="code" class="cpp">#include<string.h>
int check( char *s1,char *s2,int n );
int main()
{
	char s1[10000],s2[1000000];
	int n,i,j,k;
	int T = 563;
	scanf( "%d",&n );
	for( i = 0;i < n;++i )	{
		int key1 = 0,key2 = 0,temp = 1;  
		int len1,len2;
		int count = 0;
		scanf( "%s %s",s1,s2 );
		len1 = strlen(s1),len2 = strlen(s2);
		if( len1 > len2 )	{
			printf( "0\n" );
			break;
		}
		for( j = 0;j < len1;++j )	{
			key1 = ( key1 * 26 + s1[j] - 'A' ) % T;
			key2 = ( key2 * 26 + s2[j] - 'A' ) % T;
		}
		for( j = 0;j < len1 - 1;++j )
			temp = (temp % T * 26 % T) % T;   // printf( "%d\n",temp );
		// printf( "key1: %d  key2 : %d\n",key1,key2 );
		if( key1 == key2 && check(s1,s2,len1) )
			++count;
		for( j = 1;j <= len2 - len1;++j )	{
			int t = key2 - (s2[j-1] - 'A') * temp;
			if( t < 0 )	
				while( t < 0 )
					t += T;
			key2 = ( t * 26 + s2[j+len1-1] - 'A' ) % T;
			// printf( "ignore: %c,add %c ",s2[j-1],s2[j+len1-1] );
			// printf( "key2 : %d\n",key2 );
			if( key2 != key1 )
				continue;
			else {
				if( check( s1,s2 + j,len1 ) )
					++count;
			}
		}
		printf( "%d\n",count );
	}
	return 0;
}
int check( char *a,char *b,int n )
{
	int i = 0;
	for( i = 0;i < n;++i )
		if( a[i] != b[i] )
			return 0;
	return 1;
}

字串匹配的RabinKarp演算法就是將模式轉化為數字形式,然後在母版上尋找其數值與模式數值相同的片段,如果模式長度較長,則選用取模後所得數相同的值在進行精確驗證其是否相等。如果在文字搜尋中能夠匹配的次數很少,則其事件複雜度可以看做是O(n+m);下面程式是將字符集a-z看做是26位進位制的數值,然後對其進行求模尋找相等值,如果有在使用check函式精確驗證其正確性。