如何在 C# 中对数组执行集合减法?
Posted
技术标签:
【中文标题】如何在 C# 中对数组执行集合减法?【英文标题】:How to perform set subtraction on arrays in C#? 【发布时间】:2011-06-30 19:48:34 【问题描述】:在给定 C# 中的两个数组的情况下,执行集合减法的最简单方法是什么?显然这是 Ruby 中的dead easy。基本上我只想从数组a
中删除数组b
中的元素:
string[] a = new string[] "one", "two", "three", "four" ;
string[] b = new string[] "two", "four", "six" ;
string[] c = a - b; // not valid
c
应该等于 "one", "three"
。 b - a
将产生 "six"
。
【问题讨论】:
【参考方案1】:如果您使用的是 Linq,您可以像这样使用 Except operator:
string [] c = a.Except(b).ToArray();
编辑: CodeInChaos 提出了一个很好的观点。如果a
包含重复项,它也会删除所有重复项。使其功能与 Ruby 版本完全相同的替代方法是:
string [] c = a.Where(x=>!b.Contains(x)).ToArray();
【讨论】:
请注意,这只会返回唯一元素。因此,如果您在a
中有一个元素两次,它将只保留第一个。
太好了,谢谢——不知道我是怎么错过的。猜猜这个名字让我失望了。
替代方案将删除重复项!
请注意,您的替代代码是O(a.Length*b.Length)
。为了让它更快,你需要从b
中构造一个HashSet<T>
。
@xanatos - 这是正确的行为,从 A 中删除 B 中的所有元素。另一方面,我的替代方案将执行 'B','B' - 'A' = 'B','B'【参考方案2】:
public static IEnumerable<T> Minus<T>(this IEnumerable<T> enum1, IEnumerable<T> enum2)
Dictionary<T, int> elements = new Dictionary<T, int>();
foreach (var el in enum2)
int num = 0;
elements.TryGetValue(el, out num);
elements[el] = num + 1;
foreach (var el in enum1)
int num = 0;
if (elements.TryGetValue(el, out num) && num > 0)
elements[el] = num - 1;
else
yield return el;
这不会从 enum1 中删除重复项。说清楚:
-
'A', 'A' - 'A' == 'A'
'A', 'A' - 'A' ==
我做第一个,Enumerable.Except 做第二个。
【讨论】:
elements.Remove
应该是elements.Contains
@Keltex,这个想法是你想删除它,因为它已经被计算在内。但是,我认为它应该是 List
而不是 HashSet
,因为否则它不会考虑 a, a, a
- a, a
= a
。
不,它应该是字典,所以我仍然在 O(m * log(n)) 中(技术上可能是 O((m + 1) * log(n)) )
使用 Linq,你可以做到var elements = enum2.GroupBy(el => el).ToDictionary(elg => elg.Key, elg => elg.Count());
。以上是关于如何在 C# 中对数组执行集合减法?的主要内容,如果未能解决你的问题,请参考以下文章