Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.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_Algorithm - Fatal编程技术网

比较Java中公共元素列表的更快方法?

比较Java中公共元素列表的更快方法?,java,algorithm,Java,Algorithm,我有一个LinkedList的图(用Vector实现),我想连接不共享任何公共元素的LinkedList。我认为我现在这样做需要O(n^3)。我有一个遍历向量的for循环,然后有一个嵌套的for循环遍历向量(这样我就可以将每个列表与其他列表进行比较),然后在for循环中使用递归来比较列表 在以这种方式尝试之前,我尝试在第二个for循环中使用while循环来迭代每个列表,并使用二进制搜索来查看第二个列表是否包含每个元素,但我认为这需要相同的时间或更长的时间。 这是我的循环: public voi

我有一个LinkedList的图(用Vector实现),我想连接不共享任何公共元素的LinkedList。我认为我现在这样做需要O(n^3)。我有一个遍历向量的for循环,然后有一个嵌套的for循环遍历向量(这样我就可以将每个列表与其他列表进行比较),然后在for循环中使用递归来比较列表

在以这种方式尝试之前,我尝试在第二个for循环中使用while循环来迭代每个列表,并使用二进制搜索来查看第二个列表是否包含每个元素,但我认为这需要相同的时间或更长的时间。 这是我的循环:

 public void addEdges(){
  for(int i =0; i < size()-1; i++){
   for(int j = i+1; j < size(); j++){
    if(compatible(get(i),get(j),1,1)){
     get(i).linkTo(get(j));
     get(j).linkTo(get(i));
    }
   }
  }
 }

假设我读的是正确的,您可以用对静态方法的调用来替换兼容的方法

编辑:代码示例:

public void addEdges(){
  for(int i =0; i < size()-1; i++){
   for(int j = i+1; j < size(); j++){
    if(Collections.disjoint(get(i),get(j))){
     get(i).linkTo(get(j));
     get(j).linkTo(get(i));
    }
   }
  }
 }
public void addEdges(){
对于(int i=0;i
我可能会尝试反向索引,
元素->[包含列表的ID]
。迭代索引将告诉您哪些列表共享元素,因此无法连接

  • 步骤1:创建反向索引
  • 步骤2:创建不兼容索引,
    列表ID->[不兼容列表的ID]
  • 步骤3:迭代不兼容映射以加入兼容的列表
如果有加入兼容列表的特定规则,步骤3可能会更复杂,因为兼容性不是暂时的


一些伪Java:为了我自己,我将假设数据结构如下所示(可能我的
Bin
是您的
,或多或少):

步骤2:不兼容索引的类型为
多值映射
,其中每个箱子ID映射到不兼容箱子的箱子ID集

MultiValueMap<ID, ID> incompatibilityIndex;

for (Element e : reverseIndex.keySet()) {
    List<ID> binsWithE = reverseIndex.get(e);
    for (ID id : binsWithE) {
        incompatibilityIndex.putAll(id, binsWithE); // each bin is incompat with itself
    }
}
多值映射不兼容索引;
对于(元素e:reverseIndex.keySet()){
List binsWithE=reverseIndex.get(e);
用于(ID:binsWithE){
不兼容index.putAll(id,binsWithE);//每个bin都与自身不兼容
}
}
步骤3:现在我们可以加入任何两个不在彼此不兼容映射中的容器。由于连接两个存储箱会改变不兼容性,因此我们必须更加棘手:

Set<Bin> binsRemainingToProcess; // == original allBins
Set<Bin> binsProcessed; // == new allBins

while (binsRemainingToProcess.size() > 0) {
    Bin bin = // grab any bin to work on from binsRemainingToProcess

    // grab any compatible bins
    // could iterate until we find one, but I'm going to compute all compatible
    List<ID> compatibleBinIDs = // all bin IDs in binsRemaining...
    List<ID> incompatibleBinIDs = incompatibilityIndex.get(bin.id);
    compatibleBinIDs.removeAll(incompatibleBinIDs);

    if (compatibleBinIDs.size() > 0) {
        Bin otherBin = // some bin with ID in compatibleBinIDs

        // joining the two bins -- means joining the inner lists,
        // but also joining the incompatibilities
        joinDataStructures(bin, otherBin);
        incompatibilityIndex.putAll(bin.id, incompatibilityIndex.get(otherBinID));

        // we don't need the other bin anymore, but we may be able to join
        // the first bin to others
        binsRemainingToProcess.remove(otherBin);
    } else {
        // couldn't join with anyone; we're done with this bin and can move on
        binsRemainingToProcess.remove(bin);
        binsProcessed.add(bin);
    }
}
Set binsRemainingToProcess;//==原始allBins
设置已处理的容器;/==新allBins
while(binsRemainingToProcess.size()>0){
Bin Bin=//从binsRemainingToProcess抓取任何要处理的Bin
//抓取任何兼容的垃圾箱
//可以迭代直到找到一个,但我要计算所有兼容的
列出compatibleBinIDs=//剩余箱子中的所有箱子ID。。。
List composibilebinids=composibilityindex.get(bin.id);
可配伍的拟除虫菊酯(不可配伍的拟除虫菊酯);
if(compatibleBinIDs.size()>0){
Bin otherBin=//在compatibleBinIDs中具有ID的某些Bin
//连接两个箱子意味着连接内部列表,
//但也加入了不相容性
joinDataStructures(bin,otherBin);
compatibilityindex.putAll(bin.id,compatibilityindex.get(otherBinID));
//我们不再需要另一个垃圾箱了,但我们可以加入
//第一个垃圾桶给别人
正在处理的箱子。移除(其他箱子);
}否则{
//无法加入任何人;我们已处理完此垃圾箱,可以继续前进
正在处理的料仓。移除(料仓);
已处理的bin。添加(bin);
}
}

好的,所以最后一个比我计划的要详细得多…

我意识到你在寻找更快的方法来实现这一点,我认为@Michael Brewer Davis 提出了一种更好的方法,但在创建之前是否有解决问题的方法 名单?因此,与其在创建列表时比较列表,不如在创建列表时进行比较,这样就不必如此残酷地递归了?
(我的意思可能是设计上的改变:只对元素进行一次不平等性比较,以便不相关的元素自然地分组在一起,并可能避免递归)

我实际上想到了一种比较列表的更快方法。我列出了所有可能的元素,现在我没有列出元素,而是创建了一个长数组,长的每一位表示它们是否包含可能元素列表中的对应元素。然后,我使用&运算符比较long,看看它们是否有任何共同元素。

很高兴使代码更简单,但他的
兼容的
方法似乎依赖于对数据结构的假设,因此它应该比默认方法更有效。@Michael:我考虑过,但是我想我应该以任何一种方式发布这篇文章,以防它真的满足了他的要求。@Michael:这里的困惑是我不确定
get(I)
get(j)
返回了什么。我假设
LinkedList
,尽管
compatible
方法采用了
对象。我创建了一个扩展LinkedList的行类。很抱歉给你带来了困惑。行也被排序。不相交的方法会更有效吗?或者也会是O(n)(甚至O(n^2))?@SYL:老实说,我不确定这个方法的效率是什么,因为JavaDoc只是让实现来决定。话虽如此,如果您的
LinkedList
已排序,您可能可以使用它以获得更快的结果。。。我不太确定。我不认为我能以一种对我有帮助的方式将它们组合在一起,因为每个列表都是唯一的。我不确定你的意思。你能给我看一下示例代码还是伪代码?反向索引是以元素为键、包含列表的列表为值的映射,不兼容索引是以列表为键、不兼容列表的列表为值的映射
MultiValueMap<Element, ID> reverseIndex;

for (Bin bin : allBins) {
    for (Element e : bin) {
        reverseIndex.put(e, bin.id);
    }
}
MultiValueMap<ID, ID> incompatibilityIndex;

for (Element e : reverseIndex.keySet()) {
    List<ID> binsWithE = reverseIndex.get(e);
    for (ID id : binsWithE) {
        incompatibilityIndex.putAll(id, binsWithE); // each bin is incompat with itself
    }
}
Set<Bin> binsRemainingToProcess; // == original allBins
Set<Bin> binsProcessed; // == new allBins

while (binsRemainingToProcess.size() > 0) {
    Bin bin = // grab any bin to work on from binsRemainingToProcess

    // grab any compatible bins
    // could iterate until we find one, but I'm going to compute all compatible
    List<ID> compatibleBinIDs = // all bin IDs in binsRemaining...
    List<ID> incompatibleBinIDs = incompatibilityIndex.get(bin.id);
    compatibleBinIDs.removeAll(incompatibleBinIDs);

    if (compatibleBinIDs.size() > 0) {
        Bin otherBin = // some bin with ID in compatibleBinIDs

        // joining the two bins -- means joining the inner lists,
        // but also joining the incompatibilities
        joinDataStructures(bin, otherBin);
        incompatibilityIndex.putAll(bin.id, incompatibilityIndex.get(otherBinID));

        // we don't need the other bin anymore, but we may be able to join
        // the first bin to others
        binsRemainingToProcess.remove(otherBin);
    } else {
        // couldn't join with anyone; we're done with this bin and can move on
        binsRemainingToProcess.remove(bin);
        binsProcessed.add(bin);
    }
}