[C++]KMP算法匹配字符串

KMP算法匹配字符串

题目描述如下:

Time Limit: 1sec Memory Limit:32MB
Description
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.

问题分析

最初想到的当然是最简单的暴力匹配,但很快地发现这种做法会超时。于是在网上查找资料,有一种说法是使用KR算法,这种算法的思想是把字符串转换成hash值,然后进行hash值比较,如果相等再进行字符串比较。本以为可以,但最后发现还是WA,至今不知道什么原因。我猜测有可能是因为整数溢出了,因为字符串实在是太大了。最后找到的方法是使用KMP匹配。这种匹配其实只是省略了大量的重复匹配的时间,如果没有办法省略这样的时间,消耗的时候仍然和暴力求解一样。

以下给出博客链接
KMP算法详解

代码

#include <stdio.h>
int protection[1000000],code[80000];
int p_len, c_len, next[80000];
// next 为code字符串的预处理数组。
void get_next() {
    next[1] = 0;
    int j = 0;
    for(int i = 2; i <= c_len; ++i) {
        while (j > 0 && code[j + 1] != code[i])
            j = next[j];
        if (code[j+1] == code[i])
            j = j + 1;
        next[i] = j;
    }
}
void kmp() {
    int j = 0;
    for (int i = 1; i <= p_code; ++i) {
        while (j > 0 && code[j + 1] != protection[i])
            j = next[j];
        if (code[j+1] == protection[i])
            j = j+1;
        if (j == c_code) {
            printf("%d\n", i - c_code); 
            return ;
        }
    }
    printf("no solution\n");
}
int main() {
    while (scanf("%d", &c_code)) {
        for (int i = 1; i <= c_code; ++i)
            scanf("%d", &code[i]);
        scanf("%d", &p_code);
        for (int i = 1;i <= p_code; ++i)
            scanf("%d", &protection[i]);
        get_next();
        kmp();
    }
    return 0;
}
    原文作者:KMP算法
    原文地址: https://blog.csdn.net/stary_yan/article/details/53424805
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞