大字符串中子字符串搜索的算法

时间:2017-01-14 07:45:20

标签: java string algorithm

我只是检查一个具有最佳计算复杂度的高效算法来检查一个子字符串 - tobeVerified是否存在于一个巨大的父字符串中

我正在尝试不同的算法,但我还没找到提供O(n)

的东西

我使用HashSet提出了以下实现,它给了我O(n+m) ~ O(n)

我想检查这是否是正确的方法,或者是否可以进行任何其他优化。但是在这种方法中存在消耗更多空间的问题

String parent = "the value is very high";
    String tobeVerified = "is";
    Set wordSet = new HashSet<String>();    
    String[] words = parent.trim().toUpperCase().split("\\s+");
    //This is O(n) n - Parent Size  m - substring size
    for(String word: words){
        wordSet.add(word);      
    }
    //This is O(1)
    System.out.println(wordSet.contains(tobeVerified.toUpperCase()));
    }

2 个答案:

答案 0 :(得分:3)

经典// a ListBuffer Stream val lbStrm: Stream[ListBuffer[Set[Int]]] = Stream.iterate[ListBuffer[Set[Int]]](ant)(_.map(_.flatMap(x => ant(x) + x))) // grab the first one after the results settle lbStrm.zipWithIndex.dropWhile{case (lb,x) => lb != lbStrm(x+1)}.head._1 // ListBuffer(Set(), Set(0), Set(0), Set(0, 1), Set(0, 2), Set(0, 1), Set(0, 1, 2, 3, 4), Set(0, 5, 1, 6, 2, 3, 4), Set(0, 5, 1, 6, 2, 7, 3, 4)) 子字符串搜索算法之一是Boyer-Moore。对于足够大的字符串,它应该比public static String read() { byte[] buffer = new byte[10]; try { int numBytes = System.in.read(buffer); } catch(IOException e) { System.out.print("Error: " + e); System.exit(1); } String str = new String(buffer); int ball = 5; return (str); } O(n+m)具有更好的性能。

在上面的维基百科页面链接上有一个算法的Java实现,但是它被编写为使用String.contains数组作为输入而不是String类的实例。因此,要么修改代码以使用String参数,要么考虑将String.indexOf克隆到char[]中的额外成本O(n)。

我在维基百科代码上发现了一个小问题。它假定字符值仅在8位范围内。您可能需要修改此行:

String

要成为这样:

char[]

更新:我已正确更新维基百科页面代码,以获得final int ALPHABET_SIZE = 256; 的正确值。确认原始错误存在并编写单元测试以验证修复。

答案 1 :(得分:0)

如果分析显示您确实存在性能问题,则可以按answer by selbie中的建议进行Boyer-Moore实施。

在此之前,只需进行简单的正则表达式搜索:

String textToSearch = "the value is very high";
String wordToFind = "is";
String regex = "(?i)\\b" + Pattern.quote(wordToFind) + "\\b";
boolean found = Pattern.compile(regex).matcher(textToSearch).find();

(?i)使搜索不区分大小写,\\b匹配字边界,例如确保isthis不匹配。由于您正在进行单词搜索,Pattern.quote()可能不必要,但最好是安全而不是抱歉。