比较两个数组是否相等的最快方法是什么?

发布于 2024-10-02 09:03:39 字数 174 浏览 6 评论 0原文

我有两个对象数组,它们可能具有相同的值,但顺序不同,例如

{ "cat", "dog", "mouse", "pangolin" }

{ "dog", "pangolin", "cat", "mouse" }

我希望将这两个数组视为相等。测试这个的最快方法是什么?

I have two arrays of objects which are likely to have the same values, but in a different order, e.g.

{ "cat", "dog", "mouse", "pangolin" }

{ "dog", "pangolin", "cat", "mouse" }

I wish to treat these two arrays as equal. What's the fastest way to test this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

故事和酒 2024-10-09 09:03:39

我不能保证这是最快的,但它肯定非常有效:

bool areEquivalent = array1.Length == array2.Length 
                     && new HashSet<string>(array1).SetEquals(array2);

编辑:
SaeedAlg 和 Sandris 提出了关于不同重复频率导致此方法出现问题的有效观点。如果这很重要,我可以看到两种解决方法(没有过多考虑它们各自的效率):

1.对数组进行排序,然后按顺序比较它们。理论上,这种方法在最坏的情况下应该具有二次复杂度。
例如:

return array1.Length == array2.Length
       && array1.OrderBy(s => s).SequenceEqual(array2.OrderBy(s => s));

2.建立每个数组中字符串的频率表,然后比较它们。例如:

if(array1.Length != array2.Length)
   return false;

var f1 = array1.GroupBy(s => s)
               .Select(group => new {group.Key, Count = group.Count() });

var f2 = array2.GroupBy(s => s)
               .Select(group => new {group.Key, Count = group.Count() });

return !f1.Except(f2).Any();

I can't guarantee that this is the fastest, but it's certainly quite efficient:

bool areEquivalent = array1.Length == array2.Length 
                     && new HashSet<string>(array1).SetEquals(array2);

EDIT:
SaeedAlg and Sandris raise valid points about different frequencies of duplicates causing problems with this approach. I can see two workarounds if this is important (haven't given much thought to their respective efficiencies):

1.Sort the arrays and then compare them sequentially. This approach, in theory, should have quadratic complexity in the worst case.
E.g.:

return array1.Length == array2.Length
       && array1.OrderBy(s => s).SequenceEqual(array2.OrderBy(s => s));

2.Build up a frequency-table of strings in each array and then compare them. E.g.:

if(array1.Length != array2.Length)
   return false;

var f1 = array1.GroupBy(s => s)
               .Select(group => new {group.Key, Count = group.Count() });

var f2 = array2.GroupBy(s => s)
               .Select(group => new {group.Key, Count = group.Count() });

return !f1.Except(f2).Any();
盛夏尉蓝 2024-10-09 09:03:39

我认为唯一合理的方法就是对它们进行排序然后进行比较。

排序需要 O(n logn) 并进行比较 O(n),因此总共仍然是 O(n logn)

I think the only reasonable way is to sort them and then compare.

Sorting requires O(n logn) and comparing O(n), so that's still a total of O(n logn)

┼── 2024-10-09 09:03:39

将两个数组都转换为 HashSet 并使用 setequals

Convert both arrays to HashSets and use setequals

栖竹 2024-10-09 09:03:39

你有没有尝试过类似的东西

string[] arr1 = {"cat", "dog", "mouse", "pangolin"};

string[] arr2 = {"dog", "pangolin", "cat", "mouse"};

bool equal = arr1.Except(arr2).Count() == 0 && arr2.Except(arr1).Count() == 0;

Have you tried something like

string[] arr1 = {"cat", "dog", "mouse", "pangolin"};

string[] arr2 = {"dog", "pangolin", "cat", "mouse"};

bool equal = arr1.Except(arr2).Count() == 0 && arr2.Except(arr1).Count() == 0;
海拔太高太耀眼 2024-10-09 09:03:39

我会使用 HashSet,假设没有重复项

string[] arr1 = new string[] { "cat", "dog", "mouse", "pangolin" };
string[] arr2 = new string[] { "dog", "pangolin", "cat", "mouse" };

bool result = true;
if (arr1.Length != arr2.Length)
{
    result = false;
}
else
{
    HashSet<string> hash1 = new HashSet<string>(arr1);
    foreach (var s in arr2)
    {
        if (!hash1.Contains(s))
            result = false;
    }
}

编辑:
如果只有四个元素,跳过 HashSet 并在比较中使用 arr1.Contains 可能会更快。测量并选择最适合您的阵列大小的最快的。

I would use a HashSet, assuming there are no duplicates

string[] arr1 = new string[] { "cat", "dog", "mouse", "pangolin" };
string[] arr2 = new string[] { "dog", "pangolin", "cat", "mouse" };

bool result = true;
if (arr1.Length != arr2.Length)
{
    result = false;
}
else
{
    HashSet<string> hash1 = new HashSet<string>(arr1);
    foreach (var s in arr2)
    {
        if (!hash1.Contains(s))
            result = false;
    }
}

Edit:
If you just have four elements it might be faster to skip the HashSet and use arr1.Contains in the comparison. Measure and pick the fastest for your array size.

深巷少女 2024-10-09 09:03:39

伪代码 :

A:array
B:array
C:hashtable

if A.length != B.length then return false;

foreach objA in A
{
H = objA;
if H is not found in C.Keys then
C.add(H as key,1 as initial value);
else
C.Val[H as key]++;
}

foreach objB in B
{
H = objB;
if H is not found in C.Keys then
return false;
else
C.Val[H as key]--;
}

if(C contains non-zero value)
return false;
else
return true;

Pseudocode :

A:array
B:array
C:hashtable

if A.length != B.length then return false;

foreach objA in A
{
H = objA;
if H is not found in C.Keys then
C.add(H as key,1 as initial value);
else
C.Val[H as key]++;
}

foreach objB in B
{
H = objB;
if H is not found in C.Keys then
return false;
else
C.Val[H as key]--;
}

if(C contains non-zero value)
return false;
else
return true;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文