我有两个列表A和B(列表)。如何以最便宜的方式确定它们是否相等?我可以写一些类似'(A减B)联合(B减A)=空集'或将它们连接在一起并计算元素数量,但它相当昂贵。有解决方法吗?
答案 0 :(得分:18)
如果列表项的排序是相关的:
bool areEqual = a.SequenceEqual(b);
如果要将列表视为无序集:
// assumes that the list items are ints
bool areEqual = new HashSet<int>(a).SetEquals(b);
(SequenceEqual
方法和HashSet<T>
构造函数都具有带IEqualityComparer<T>
参数的重载,如果您需要该功能。)
答案 1 :(得分:7)
嗯,这取决于你如何解释你的名单。
如果您将它们视为元组(因此列表中元素的顺序很重要),那么您可以使用此代码:
public bool AreEqual<T>(IList<T> A, IList<T> B)
{
if (A.Count != B.Count)
return false;
for (int i = 0; i < A.Count; i++)
if (!A[i].Equals(B[i]))
return false;
}
如果您将列表视为集合(因此元素的顺序无关紧要),那么......您使用的是错误的数据结构:
public bool AreEqual<T>(IList<T> A, IList<T> B)
{
HashSet<T> setA = new HashSet<T>(A);
return setA.SetEquals(B);
}
答案 2 :(得分:1)
这取决于你的意思“列表是平等的”。如果你的意思是它们包含相同的对象,Daniel建议的解决方案很好,只需要Union()两个列表并计算项目。
如果“相等”意味着他们有相同的项目以相同的顺序,那么您最好比较两个列表的计数,然后如果它们具有相同的计数,则只需使用普通for loop
进行迭代,以比较同一索引处两个列表中的每个元素。不太好,但你很难快。
答案 3 :(得分:1)
除非对列表进行排序,否则这里没有快捷方式,在这种情况下,您可以逐个比较这些元素。显然我认为顺序无关紧要,否则很明显你可以逐个比较它们。
否则,我建议您为大型项目列表获得的最有效算法可能是这样的,使用哈希表来跟踪您所看到的内容(警告:尚未测试,但应该清楚我得到了什么。)
public static bool IsEqual<T>(this List<T> x1, List<T> x2)
{
if(x1.Count != x2.Count) return false;
var x1Elements = new Dictionary<T, int>();
foreach(var item in x1)
{
int n; x1Elements.TryGetValue(item, out n);
x1Elements[item] = n+1;
}
foreach(var item in x2)
{
int n; x1Elements.TryGetValue(item, out n);
if(n <= 0) return false; // this element was in x2 but not x1
else x1Elements[item] = n-1;
}
// make sure x1 didn't have any elements
// that weren't in x2
return x1Elements.Values.All(x => x == 0);
}
答案 4 :(得分:-1)
第一次拍摄 - 如果它们包含相同的项目,则两个列表的并集应该具有与两个列表中的任何一个相同的项目数。
listA.Union(listB).Count() == listA.Count()
注意:如果一个列表为空,则失败。
但它可能仍然是O(n²)
操作。
另一种解决方案 - 列表必须具有相同的长度和列表A减去列表B不得包含任何元素。
(listA.Count() == listB.Count()) && !listA.Except(listB).Any()