[英]What's the fastest way to compare two arrays for equality?
我有兩個對象數組,它們可能具有相同的值,但順序不同,例如
{ "cat", "dog", "mouse", "pangolin" }
{ "dog", "pangolin", "cat", "mouse" }
我希望將這兩個數組視為相等。 測試這個的最快方法是什么?
我不能保證這是最快的 ,但它肯定非常有效:
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();
我認為唯一合理的方法是對它們進行排序然后進行比較。
排序需要O(n logn)
並比較O(n)
,因此仍然是O(n logn)
的總和
你嘗試過類似的東西嗎?
string[] arr1 = {"cat", "dog", "mouse", "pangolin"};
string[] arr2 = {"dog", "pangolin", "cat", "mouse"};
bool equal = arr1.Except(arr2).Count() == 0 && arr2.Except(arr1).Count() == 0;
將兩個數組轉換為HashSet並使用setequals
假設沒有重復項,我會使用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可能會更快。 測量並選擇最快的陣列大小。
偽代碼:
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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.