String matching using Rabin-Karp Algorithm

Problem

Brian is an enthusiast of computer games, especially those that simulate virtual reality. Now he is in front of the Star Gate. In order to open the gate he must break the protection as quickly as he can. Breaking the protection means to match a given code (a sequence of numbers) against the gate protection (a very long sequence of numbers). The starting position of the first occurrence of the code within the sequence opens the gate. Can you help him?

The code is a sequence of at most 60000 integer numbers between 0 and 255. The gate protection contains integer numbers between 0 and 255. Your program must find the first match if there is one, or report the absence of a match.


Input

The text input file contains several data sets. Each data set has the following format:


l the length of the code


l the sequence of numbers representing the code


l the number of integers in the gate protection


l the sequence of numbers representing the gate protection


code_dimension

integer1 integer2 … integercode_dimension

protection_dimension

integer1 integer2 … integerprotection_dimension


White spaces may occur freely in the input.

Output

The results must be printed on the standard output. For each given data set, print the result on a separate line. The result is a number that represents the position (starting from zero) of the first occurrence of the code in the gate protection, or the message no solution if there is no match.



// (Introduction to algorithms 32.2  Rabin-Karp算法)  
#include 
< iostream >
#include 
< stdio.h >
using   namespace  std;


void  RABIN_KARP_MATCHER(unsigned  char *  T,  int  len_T, unsigned  char *  P,  int  len_P,  int  d,  int  q)
{
    
int i;
    
int n=len_T;
    
int m=len_P;
    
int h=1;
    
for(i=1; i<=m-1; i++)
    
{
        h
=(h*d)%q;
    }

    
int p=0
    
int    t=0;
    
for(i=0; i<m; i++
    
{
        p
=(d*p+P[i])%q;
        t
=(d*t+T[i])%q;
    }

    
int s;
    
for(s=0; s<n-m+1; s++
    
{
        
if(p==t)
        
{
            
for(i=0; i<m; i++
            
{
                
if(P[i]!=T[s+i])
                    
break;
            }

            
if(i==m)
            
{
                cout<<s<<endl;
                 return;
            }

        }

        
if(s<n-m)
            t
=mod((d*(t-T[s]*h)+T[s+m]),q);
    }

    cout
<<"no solution ";
    
return ;
}


int  main()
{
    
int code_len;
    
int protect;
    
int i;
    
while(scanf("%d"&code_len)!=EOF) 
    
{
        unsigned 
char* code=new unsigned char[code_len];
        
for(i=0; i<code_len; i++
        
{
            scanf(
"%hu"&code[i]);
        }

        scanf(
"%d"&protect);
        unsigned 
char* pro=new unsigned char[protect];
        
for(i=0; i<protect; i++
        
{
            scanf(
"%hu"&pro[i]);
        }

        RABIN_KARP_MATCHER(pro, protect, code , code_len, 128,
6999997);  // d*q < 字长
    }

    
return 0;
}
 
 

width="728" scrolling="no" height="90" frameborder="0" align="middle" src="http://download1.csdn.net/down3/20070601/01184120111.htm" marginheight="0" marginwidth="0">
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
(a) We can model this problem as a bipartite graph where one set of vertices represents the customers and the other set represents the representatives. We draw an edge between a customer and a representative only if the representative is qualified to serve that customer. Then, we can use the Hopcroft-Karp algorithm to find a maximum matching in this bipartite graph. If the size of the maximum matching is n, then all customers can be served simultaneously by a qualified representative. We can assign each customer the representative they are matched with. (b) To check whether a representative r can serve the VIP customer while the other n-1 customers can be served by qualified representatives, we first remove all edges incident to r from the bipartite graph. Then, we check whether the remaining subgraph has a matching that covers all customers except the VIP customer. If such a matching exists, then r can serve the VIP customer while the other n-1 customers can be served by qualified representatives. Otherwise, r cannot serve the VIP customer without affecting the capacity to serve the other customers. To implement this algorithm, we can modify the Hopcroft-Karp algorithm as follows. We start by removing all edges incident to r and finding a maximum matching in the remaining subgraph. If the size of the maximum matching is less than n-1, then r cannot serve the VIP customer. Otherwise, we add the VIP customer to the matching and check whether the resulting matching covers all customers. If it does, then r can serve the VIP customer while the other n-1 customers can be served by qualified representatives. Otherwise, r cannot serve the VIP customer without affecting the capacity to serve the other customers. The time complexity of this algorithm is O(n^3), since we need to run the Hopcroft-Karp algorithm twice, once on the original bipartite graph and once on the subgraph with edges incident to r removed.翻译
最新发布
05-22
(a)我们可以将这个问题建模为一个二分图,其中一个顶点集表示顾客,另一个表示代表。仅当代表有资格为该顾客提供服务时,我们在顾客和代表之间绘制一条边。然后,我们可以使用Hopcroft-Karp算法在这个二分图中找到一个最大匹配。如果最大匹配的大小为n,则所有顾客都可以同时由合格的代表提供服务。我们可以为每个顾客分配他们匹配的代表。 (b)要检查代表r是否可以为VIP客户提供服务,同时其他n-1个客户可以由合格的代表提供服务,我们首先从二分图中删除与r相连的所有边。然后,我们检查剩余子图是否有一个匹配覆盖除VIP客户以外的所有顾客。如果存在这样的匹配,则r可以为VIP客户提供服务,而其他n-1个客户可以由合格的代表提供服务。否则,r不能为VIP客户提供服务,而不影响为其他客户提供服务的能力。 要实现这个算法,我们可以修改Hopcroft-Karp算法如下。我们首先删除所有与r相连的边,并在剩余的子图中找到一个最大匹配。如果最大匹配的大小小于n-1,则r不能为VIP客户提供服务。否则,我们将VIP客户添加到匹配中,并检查结果匹配是否覆盖所有顾客。如果是,则r可以为VIP客户提供服务,同时其他n-1个客户可以由合格的代表提供服务。否则,r不能为VIP客户提供服务,而不影响为其他客户提供服务的能力。该算法的时间复杂度为O(n^3),因为我们需要在原始二分图和删除与r相连的边的子图上运行Hopcroft-Karp算法两次。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值