Java 搜寻及;大整数集的差分

Java 搜寻及;大整数集的差分,java,algorithm,Java,Algorithm,我有两个大整数数组。我必须得到这些数组的差异(即第二个数组中的元素,而不是第一个数组中的元素,反之亦然)。我正在实现一个线性搜索,并将差异存储在一个数组中。有什么方法可以让我做得更快(线性时间)?如果将一个数组放入哈希集中,然后遍历另一个数组,探测哈希集,很容易得到O(n+m)时间。当然,如果对数组进行了排序,那么就可以直接使用O(n+m)。我认为可能,这取决于您的过度需求。您可以将列表分解为几个小集合,并使用线程处理每个集合,将结果合并回一个集中池 虽然不太困难,但您需要进行一些管理,以便将结

我有两个大整数数组。我必须得到这些数组的差异(即第二个数组中的元素,而不是第一个数组中的元素,反之亦然)。我正在实现一个线性搜索,并将差异存储在一个数组中。有什么方法可以让我做得更快(线性时间)?

如果将一个数组放入哈希集中,然后遍历另一个数组,探测哈希集,很容易得到O(n+m)时间。当然,如果对数组进行了排序,那么就可以直接使用O(n+m)。

我认为可能,这取决于您的过度需求。您可以将列表分解为几个小集合,并使用线程处理每个集合,将结果合并回一个集中池

虽然不太困难,但您需要进行一些管理,以便将结果组织回正确的顺序(因为线程2可能在线程1之前完成),并监视流程以了解其何时完成


您可以查看以了解更多信息,哈希是好的,但是集合数据结构呢

stromberg@aw50 ~ $ /usr/local/pypy-1.9/bin/pypy
Python 2.7.2 (341e1e3821ff, Jun 07 2012, 15:38:48)
[PyPy 1.9.0 with GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``<arigato> the AI state is indeed
close''
>>>> s1 = set(range(10))
>>>> s2 = set(range(5,15))
>>>> s1
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>>> s2
set([5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
>>>> s1 - s2
set([0, 1, 2, 3, 4])
>>>> s2 - s1
set([10, 11, 12, 13, 14])
>>>> s1 & s2
set([8, 9, 5, 6, 7])
>>>> s1 | s2
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
>>>>
stromberg@aw50~$/usr/local/pypy-1.9/bin/pypy
Python 2.7.2(341E3821FF,2012年6月7日,15:38:48)
linux2上的[PyPy 1.9.0和GCC 4.4.3]
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
现在我们来看一件完全不同的事情:`人工智能国家确实
关闭“
>>>>s1=设定值(范围(10))
>>>>s2=设定值(范围(5,15))
>>>>s1
集合([0,1,2,3,4,5,6,7,8,9])
>>>>s2
集合([5,6,7,8,9,10,11,12,13,14])
>>>>s1-s2
集合([0,1,2,3,4])
>>>>s2-s1
集合([10,11,12,13,14])
>>>>s1和s2
集合([8,9,5,6,7])
>>>>s1 | s2
集合([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14])
>>>>
我想这是一种方便的方法,对于同时存储在内存中的列表,这是一种快速的方法

还有像磁盘上的btree或bloom过滤器之类的东西

使用BTrees,您不必将所有内容都放入内存中,并且可以执行类似于合并排序的合并步骤的差异化操作。它们基本上是一个有序的数据库表


对于Bloom过滤器来说,如果你需要过滤掉需要考虑的事情的数量,它们是很好的;它们是概率的,可以给出类似“这肯定不在集合中”和“这几乎肯定在集合中”的答案。bloom过滤器的主要优点是,它们只需要很少的内存(有时每个元素只需要一位)。Nice实现将允许您指定最大允许错误概率。例如,检测*ix硬链接几乎是一个集合成员问题,bloom过滤器非常适合这个问题-它们会为您提供一个可能的硬链接的简短列表,之后可以快速100%准确,因为硬链接的数量往往很小,即使实际文件的数量很大。

您不需要任何花哨的东西。如果对数组进行了排序,则对每个数组进行一次遍历就足以获得差异。只需在每个数组中保留一个索引,如果索引指向相等的元素,则增加两个索引,否则将较低的元素添加到返回数组中并增加其索引

下面是代码,在Go中,它可以执行以下操作:


这个解决方案需要O(n+m)时间和O(n+m)空间,你真的做不到比这更好的了。此外,它没有涉及哈希表的解决方案所具有的开销。

这是实现目标的一种直截了当的方法:

public static Set<Integer> foundInFirstButNotSecond(int[] first,
        int[] second) {
    Set<Integer> secondSet = new HashSet<Integer>(second.length);
    for (Integer i :
            second) {
        secondSet.add(i);
    }
    Set<Integer> resultSet = new HashSet<Integer>(first.length);
    for (Integer j :
            first) {
        if (!secondSet.contains(j)) {
            // Current integer from first not found in second
            resultSet.add(j);
        }
    }
    return resultSet;
}

您将得到一组内容为[1,2,3,4]的内容。(请注意,HashSet不保证任何特定的顺序,因此您也可以获得该顺序的无序变体。)

假设两个数组已排序,您可以使用两个滑动指针来查找差异。时间复杂度为O(n+m),空间复杂度为O(max(n,m))

void set_差异(标准::向量和数组1,标准::向量和数组2,标准::向量和输出)
{
自动索引1=0;
自动指数x2=0;
而(index1!=array1.size()&index2!=array2.size())
{//由于数组已排序,当我们发现一个更大的数字时,我们可以停止向右查找
而((array1[index1]
我的数组已排序。请详细说明或建议一些哈希集解决方案的链接好吗?我是新来的,我想了解更多…但是如果他们被分类了,你就不需要了。在这种情况下,两个数组只需检查一次,O(n+m)。数组是否已排序?是否可以使用额外的空间?
public static void main(String[] args) {
    int[] first = new int[]{1, 2, 3, 4, 5, 6};
    int[] second = new int[]{5, 6, 7, 8};
    System.out.println("In first but not second: " + ArrayCompare.
            foundInFirstButNotSecond(first, second));
}
    void set_difference(std::vector<int> & array1,std::vector<int> & array2,std::vector<int> & output ) 
{
    auto index1 =  0 ;
    auto index2 = 0 ;
    while (index1 != array1.size() & index2 != array2.size()) 
    {       //since the arrays are sorted, we can stop looking right when we find a number bigger
        while ((array1[index1] < array2[index2]) & index2 != array2.size() )  
            index2++ ;
        if (array1[index1] != array2[index2]) //array1[index1] is not array2
            output.push_back(array1[index1]);
        index1++ ;
    }
}