2010-10-13 41 views
0

您好,我正在尝试从C算法的C书中编写KMP search的C#版本。 无法找到我的算法中的缺陷。有人会帮忙吗?帮助修复我的KMP搜索算法

static int KMP(string p, string str) { 
    int m = p.Length; 
    int n = str.Length; 
    int i; 
    int j; 

    int[] next = new int[m]; 
    next[0] = -1; 

    for (i = 0, j = -1; i < m; i++, j++, next[i] = j) { 
             //Getting index out of bounds 
     while (j > 0 && p[i] != p[j]) j = next[j]; 
    } 

    for (i = 0, j = 0; i < n && j < m; i++, j++) { 
     while (j >= 0 && p[j] != str[i]) j = next[j]; 
     if (j == m) return i - m; 
    } 

    return -1; 
} 

回答

1

简单的回答是在第一环路I ++是下一个之前沉降[I] = j的等搜索字符串的最后一个字符其试图设置下一个[M + 1]到j - 这会导致一个索引超出界限例外。尝试更改顺序:

for (i = 0, j = -1; i < m; next[i] = j, i++, j++) 

更基本的是,尝试将实现分解为可测试部分。例如,您可以为第一个循环提取可测试方法,因为它正在为搜索词构建计算表。首先:

public int[] BuildTable(string word) 
{ 
    // todo 
} 

以及基于Wiki描述

[Test] 
public void Should_get_computed_table_0_0_0_0_1_2_given_ABCDABD() 
{ 
    const string input = "ABCDABD"; 
    var result = BuildTable(input); 
    result.Length.ShouldBeEqualTo(input.Length); 
    result[0].ShouldBeEqualTo(-1); 
    result[1].ShouldBeEqualTo(0); 
    result[2].ShouldBeEqualTo(0); 
    result[3].ShouldBeEqualTo(0); 
    result[4].ShouldBeEqualTo(0); 
    result[5].ShouldBeEqualTo(1); 
    result[6].ShouldBeEqualTo(2); 
} 

[Test] 
public void Should_get_computed_table_0_1_2_3_4_5_given_AAAAAAA() 
{ 
    const string input = "AAAAAAA"; 
    var result = BuildTable(input); 
    result.Length.ShouldBeEqualTo(input.Length); 
    result[0].ShouldBeEqualTo(-1); 
    result[1].ShouldBeEqualTo(0); 
    result[2].ShouldBeEqualTo(1); 
    result[3].ShouldBeEqualTo(2); 
    result[4].ShouldBeEqualTo(3); 
    result[5].ShouldBeEqualTo(4); 
    result[6].ShouldBeEqualTo(5); 
} 

接下来写的KMP方法的一个或多个测试一些NUnit tests

[Test] 
public void Should_get_15_given_text_ABC_ABCDAB_ABCDABCDABDE_and_word_ABCDABD() 
{ 
    const string text = "ABC ABCDAB ABCDABCDABDE"; 
    const string word = "ABCDABD"; 
    int location = KMP(word, text); 
    location.ShouldBeEqualTo(15); 
} 

然后实现使用该算法的维基描述中使用的结构,它应该走到一起给你。

public int KMP(string word, string textToBeSearched) 
{ 
    var table = BuildTable(word); 
    // rest of algorithm 
}