Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.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 实现子序列匹配的sortedMap_Java_Dictionary_Data Structures_Treemap_Sortedmap - Fatal编程技术网

Java 实现子序列匹配的sortedMap

Java 实现子序列匹配的sortedMap,java,dictionary,data-structures,treemap,sortedmap,Java,Dictionary,Data Structures,Treemap,Sortedmap,我想实现一个带有键和值的sortedMap,这样就可以通过提供一些子序列来搜索键。例如,地图包含3个条目: abcd -> obj1 def -> obj2 abccd -> obj3 对于查询ac,结果应该是包含第一个和第三个条目的子映射,但是对于查询acc,只应该返回第三个条目 我应该在内部使用什么样的数据结构来高效地返回这样的子映射?例如,Treemap将密钥存储在树(trie)中,以根据前缀有效地返回submap?注意:我的解决方案在查找子字符串时有效。阅读编辑 解决

我想实现一个带有键和值的sortedMap,这样就可以通过提供一些子序列来搜索键。例如,地图包含3个条目:

abcd -> obj1
def -> obj2
abccd -> obj3
对于查询
ac
,结果应该是包含第一个和第三个条目的子映射,但是对于查询
acc
,只应该返回第三个条目


我应该在内部使用什么样的数据结构来高效地返回这样的子映射?例如,
Treemap
将密钥存储在树(trie)中,以根据前缀有效地返回submap?

注意:我的解决方案在查找子字符串时有效。阅读编辑

解决方案:

ab -> obj1
cde -> obj1
bad -> obj2
使用前缀数据结构:

您需要存储:

abcd -> obj1
作为:

为了找到您的结果,您需要深入到trie中,以满足条件,并从那里找到所有可能的解决方案

示例:

ab -> obj1
cde -> obj1
bad -> obj2
我们将在Trie中插入以下条目:

ab -> obj1
b -> obj1
cde -> obj1
de -> obj1
e -> obj1
bad -> obj2
ad -> obj2
d -> obj2
现在想象一下我们在寻找下一个条目:

d
Trie中字符d的第一个下移。在那之后,我们将继续。我们已经在obj2,如果我们在obj1移动字符e。所以我们可以用条目d得到它们

cd
首先我们移动字符c,然后移动字符d。现在我们看到DFS,我们能找到的唯一路径是添加字符e,这将导致obj1

efg
Trie中没有满足out条件的路径,因此我们得不到解

编辑:

ab -> obj1
cde -> obj1
bad -> obj2
如果我们正在寻找原始元素的子字符串,我的解决方案是有效的。要修改我的解决方案,使其适用于任何非传染性子字符串,您必须在Trie中插入所有置换

您的“字符”可以在传统的搜索引擎和查询中解释为术语

根据这一评论:

abcd的所有子序列,如a、b、c、d、ab、ac、ad、bc、bd、cd、, abc、abd、acd、abcd等在查询时应返回带有 abcd->obj1作为其条目之一

我们可以解释为,如果文档中有Aspid Beaver Cherokee Deer(ABCD)一词,则在搜索该文档中的任一词或其任何组合时,都应返回该文档

您要为此构建的是一个。有关更多详细信息,请参阅。基本上,您将为每个“字符”(=搜索引擎语音中的术语)构建一个
哈希映射或查找表(没有那么多字符),其中查找将以升序返回所有出现(=搜索引擎语音中的文档)的
objX

若要查找与一组字符关联的所有对象,请将每个字符的集合合并。因为它们是有序的,所以可以在线性时间内计算集合交点

如果查询
ba
不应与
abc
键匹配,则可以优化查找表/
HashMap
以存储字符位置(例如:存储“在位置0的Obj1中找到b”,“在位置1的Obj1中找到a”,而不是丢弃位置)。计算搜索交集时,您将按搜索顺序进行,并放弃具有错误相对顺序的匹配

这是搜索引擎的常规操作,已经从性能方面进行了详尽的分析


编辑:性能


如果不同的“术语”数量较少(例如:26个小写英文字母),您可以通过添加n-gram作为术语(其中,对于“abc”,您可以添加“a”、“b”、“c”、“ab”、“ac”、“bc”和“abc”)来加快这一速度。同样的规则也适用于一半的搜索,而且由于预期会出现重叠,因此可以使用Sasha的技巧来避免存储索引。

为了总结我在评论中写的内容,我将如下所示:

  • 使用条目[2字符子序列->单词列表]创建附加索引
    HashMap
  • 添加时:从给定单词生成所有不同的2字符子序列,将该单词添加到索引映射的每个对应条目中
  • 查询:从一个查询中生成所有不同的2字符子序列,其中找到一个对应于索引映射中最短列表的子序列,获取该列表。按完整查询对其进行过滤,并从主映射中收集相应的值

  • 如果查询由一个字符组成,则执行完全扫描。我相信这会比为单个字符创建额外的索引具有更好的空间/复杂性,尤其是当单字符查询很少时。

    您可以尝试使用带有通配符的aho-corasick。Aho Corasick是一种更快的多模式匹配算法,它使用通配符提供所有子字符串。您可以在codeplex()上尝试我的php实现。例如,对基因模式使用通配符的单元测试:

    $tree = new Ahocorasick\Ahocorasick();
    $tree->add("AC");
    $tree->add("GTG");
    $tree->add("AACT");
    echo $tree->match("ACCGAGTGCGTGGACAAACTACGATTGTGGAATGAACT","AC*GT");
    $this->expectOutputString("ACCGAGT,ACCGAGTGCGT,ACCGAGTGCGTGGACAAACTACGATTGT,ACAAACTACGATTGT,ACTACGATTGT,ACGATTGT");
    
    /**
    *@作者viborole
    *
    */
    公共类排序的子序列{
    /**
    *@param args
    */
    公共静态void main(字符串[]args){
    映射数据=新的HashMap();
    数据输入(“abcd”、“obj1”);
    数据输入(“def”、“obj2”);
    数据。put(“abccd”、“obj3”);
    字符串query=“acc”;
    搜索(查询、数据);
    }
    私有静态无效搜索(字符串查询、地图数据){
    for(Map.Entry:data.entrySet())
    {
    String key=entry.getKey();
    char[]k=key.toCharArray();
    char[]q=query.toCharArray();
    int kpos=0;
    char[]found=新字符[q.length];
    对于(int i=0;i0){
    kpos++;
    }
    
    对于(int j=kpos;jfor query
    bc
    ,您的地图是否应该返回第一个和第三个条目?对于查询“ca”它应该返回第一个和第三个条目吗?还是不返回?@stephen..我为我的英语不好道歉,我的意思是,abcd的所有子序列,例如a、b、c、d、ab、ac、ad、bc、bd、cd、abc、abd、acd、abcd等,当被查询时,应该返回一个子映射,其中包含abcd->obj1项。@lostmind
    da
    也是
    ab的2字符排列cd
    @我最不了解,但OP明确表示他需要保持元素的顺序,所以他需要