C# 在高性能中比较int数组

C# 在高性能中比较int数组,c#,arrays,algorithm,data-structures,C#,Arrays,Algorithm,Data Structures,我不记得我在大学的日子里,如何比较两个未排序的int数组并找到匹配数? 每个值在其自己的数组中都是唯一的,并且两个数组的大小相同 比如说 int[5] a1 = new []{1,2,4,5,0} int[5] a2 = new []{2,4,11,-6,7} int numOfMatches = FindMatchesInPerformanceOfNLogN(a1,a2); 有人记得吗?您可以使用LINQ: var a1 = new int[5] {1, 2, 4, 5, 0}; var

我不记得我在大学的日子里,如何比较两个未排序的int数组并找到匹配数? 每个值在其自己的数组中都是唯一的,并且两个数组的大小相同

比如说

int[5] a1 = new []{1,2,4,5,0}
int[5] a2 = new []{2,4,11,-6,7}

int numOfMatches = FindMatchesInPerformanceOfNLogN(a1,a2);
有人记得吗?

您可以使用LINQ:

var a1 = new int[5] {1, 2, 4, 5, 0};
var a2 = new int[5] {2, 4, 11, -6, 7};
var matches = a1.Intersect(a2).Count();

我不确定你是在要求一个直截了当的方法还是最快/最好的方法…

我知道你有两种方法(参考:):

递归(伪代码)

效率

顺序搜索(伪代码)


我不知道O(logn)搜索算法,除非它被排序

我不知道这是不是最快的方法,但你可以做到

int[] a1 = new []{1,2,4,5,0};
int[] a2 = new []{2,4,11,-6,7};
var result = a1.Intersect(a2).Count();

当Intersect()在IEnumerable上运行时,值得将其与其他针对int优化的方法进行比较。

必须对一个数组进行排序,以便在n*log(n)中进行比较。也就是说,对于未排序数组(n)中的每一项,您都要在已排序数组(log(n))上执行二进制搜索。如果两个线程都未排序,我看不到在n*log(n)中进行比较的方法。

这个问题也适用于并行化:生成n1个线程,让每个线程比较a1的元素和a2的n2元素,然后求和值。可能比较慢,但有趣的是,产生Nav*N2线程同时进行所有比较,然后减少。如果P>>max(n1,n2)在第一种情况下,P>>n1*n2在第二种情况下,你可以用O(n)在第一种情况下,用O(logn)在第二种情况下完成整个过程。

  • 连接两个数组
  • 对结果进行快速排序
  • 从数组[1]单步执行到数组[array.length-1],并对照数组[i-1]检查数组[i]

  • 如果它们是相同的,则您有一个副本。这也应该是O(n*log(n)),并且每次检查都不需要进行二进制搜索。

    如果可以将其中一个数组的内容存储在
    哈希映射中,则可以通过查看
    哈希映射中是否存在元素来检查另一个数组中是否存在元素。这是O(n)。

    数组中的值是否有上限,是否可能有相同的值?对于未绑定的值,没有比2*sort(=O(n logn))和compare(=O(n))->O(n logn)一次排序(n logn)和一次二分搜索(n元素*logn)更好的解决方案了吗?在这里对答案进行了一些投票,以弥补(我认为)在没有充分理由的情况下否决了所有答案的人。在n*log(n)中,你如何比较拜托?似乎有很多随机的否决票,没有任何评论。所有这些答案对我来说似乎都是合理的。第一种算法是对所有项的简单for循环的递归实现,因此复杂性是相同的,O(N)。(顺便说一句,我不是落选者)@Don:谢谢你的评论。如果你用它来比较,正如开场白所说的,顺便说一句,它是O(N^2)。这是你能做的最差的了,实际上是m*log(n),m=未排序数组的大小,n=已排序数组的大小。如果与未排序的数组相比,您的排序数组非常小,那么性能将再次接近O(n)。那么,进行排序的nlog(n)加上进行搜索的mlog(n)不是很小吗?如果您也进行排序,则是的。但是大O不关心常量()。如果你愿意容忍小概率的误报,也可以使用bloom过滤器。
    May be O(log n) though I have not tried it.
    
    public boolean contains(Object anEntry)
    {   
        boolean found = false;
        for (int index = 0; !found && (index < length); index++) {
        if (anEntry.equals(entry[index]))
                found = true;
        } 
        return found;
    } 
    
    Best case  O(1)
        Locate desired item first
    Worst case  O(n)
        Must look at all the items
    Average case O(n)
        Must look at half the items 
        O(n/2) is still O(n)
    
    int[] a1 = new []{1,2,4,5,0};
    int[] a2 = new []{2,4,11,-6,7};
    var result = a1.Intersect(a2).Count();