Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 一种在字母数组中搜索单词的算法_Java_Arrays_Algorithm_Search - Fatal编程技术网

Java 一种在字母数组中搜索单词的算法

Java 一种在字母数组中搜索单词的算法,java,arrays,algorithm,search,Java,Arrays,Algorithm,Search,所以我有一个数组,我必须搜索单词 阵列: 0 1 2 3 4 5 6 7 8 9 10 11 text g t c a n d l e t j a q 关键是: 2 can 2 candle 3 a 3 an 3 and 6 let 10 a 数字是从正在搜索的数组开始的偏移量,字符串是在该偏移量处找到的字典中的单词。请注意,多个单词可以从同一偏移量开始,同一个单词可以在多个位置找到。

所以我有一个数组,我必须搜索单词

阵列:

        0   1   2   3   4   5   6   7   8   9   10  11
text    g   t   c   a   n   d   l   e   t   j   a   q
关键是:

2 can
2 candle
3 a
3 an
3 and
6 let
10 a
数字是从正在搜索的数组开始的偏移量,字符串是在该偏移量处找到的字典中的单词。请注意,多个单词可以从同一偏移量开始,同一个单词可以在多个位置找到。还要注意,单词可以重叠

这是我写的代码:

public ArrayList<Location> findWords(String[] dictionary, String text) {
    int keyLength = text.length();
    int dtLength = dictionary.length;

    ArrayList<Location> results;
    results = new ArrayList<>();

    for (int k = 0; k < keyLength; k++) {
        for (int d = 0; d < dtLength; d++) {
            if (dthasKey(dictionary[d], text, k)) {
                Location loc = new Location(k, dictionary[d]);
                results.add(loc);
            }
        }
    }
    return results;
}

private boolean dthasKey(String key, String text, int pos) {
    for (int i = 0; i < key.length(); i++) {
        if (key.length() >= text.length() - pos)
            return false;
        while (key.charAt(i) != text.charAt(pos + i)) {
            return false;
        }
    }
    return true;
}
public ArrayList findWords(字符串[]字典,字符串文本){
int keyLength=text.length();
int dtLength=dictionary.length;
ArrayList结果;
结果=新的ArrayList();
for(int k=0;k=text.length()-pos)
返回false;
while(key.charAt(i)!=text.charAt(pos+i)){
返回false;
}
}
返回true;
}
我想知道是否有更好的办法来解决这个问题。如果你们也能提供最差的时间复杂度,那就太好了。我写的是:
O(k*n*m)
式中,m是该区域的大小 字典,n是文本的大小,k是文本的长度
最长的单词。

您可以为每个单词创建一个自动机(只接受该单词),然后同时在所有自动机中运行给定的文本,这将导致O(m*k^2+n)

解决问题的标准方法是使用,它从字典中构建一个自动机,然后可以快速找到传递给它的字符串中的所有单词。谷歌搜索揭示了许多Java实现

构建自动机是O(n),其中n是字典中所有单词的字符数。但这是一次性的费用。您可以使用该自动机在多个文档中搜索单词

搜索文档中的单词是O(m+z),其中m是文档中的字符数,z是找到的匹配项数


我不知道Aho Corasick是否是最快的算法,但它非常快。而且现有的Java实现将是一个巨大的优势。但实施起来并不特别困难。最初的论文非常可读,尽管在“点击”之前可能需要反复阅读、思考和阅读。伪代码示例非常详细,您可以将其用作实现的基础。我使用该文档为一篇文章创建了一个索引。

将字典设置为
HashSet
,这样你就有了
O(k*n)
如果要在整个数组中搜索每个可能的单词(例如,整个字符串,整个字符串减去1个字母,然后是2个字母,等等),那么你的时间复杂度就最差了我不知道正则表达式的复杂性,但我想你可以试试。标准的解决方案是,从字典中构建一个自动机(一次性成本),然后可以快速找到传递给它的字符串中的所有单词。Google搜索揭示了许多Java实现。Aho Corasick搜索算法的时间复杂度为O(n+z),其中n是要搜索的文本的长度,z是找到的匹配数。那是在树建成之后。自动机的构造是O(n),但具有相当高的常数。然而,这是一次性的费用。也就是说,从字典中构造一次自动机,并使用该自动机搜索多个字符串或文档。谢谢@Jim。这确实有帮助:)O(n)应该足够了:D