任何想法,关于如何检查是否该名单是一个子集中的另一个?

具体地说,我有

List<double> t1 = new List<double> { 1, 3, 5 };
List<double> t2 = new List<double> { 1, 5 };

如何检查,t2的一个子集的t1,使用皇宫?

有帮助吗?

解决方案

bool isSubset = !t2.Except(t1).Any();

其他提示

使用HashSet的,而不是名单,如果有台工作。然后可以简单地使用 IsSubsetOf()

HashSet<double> t1 = new HashSet<double>{1,3,5};
HashSet<double> t2 = new HashSet<double>{1,5};

bool isSubset = t2.IsSubsetOf(t1);

遗憾的是它不使用LINQ。 : - (

如果你需要使用的名单,然后@ Jared的解决方案需要提醒的工作,你将需要删除任何存在的重复元素。

如果你是 单元测试 你也可以利用的 CollectionAssert.IsSubsetOf 方法:

CollectionAssert.IsSubsetOf(subset, superset);

在上述情况下这意味着:

CollectionAssert.IsSubsetOf(t2, t1);

@ Cameron的溶液作为扩展方法:

public static bool IsSubsetOf<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
    return !a.Except(b).Any();
}

用法:

bool isSubset = t2.IsSubsetOf(t1);

(这是类似的,但并不完全一样@上发布一个迈克尔的博客)

这比贴在这里,特别是顶部溶液其他一个显著更有效的解决方案:

bool isSubset = t2.All(elem => t1.Contains(elem));

如果你能找到在T2中的单个元素,是不是在T1,那么你知道,T2是不是T1的一个子集。这种方法的优点是它所做的一切原地的,而不分配额外的空间,不像使用。除或.Intersect的解决方案。此外,该解决方案能够为它发现违反子集条件的单个元素尽快打破,而其他人继续搜索。下面是解决方案,这是只有稍快在我的测试比上述速记溶液的最佳长形式。

bool isSubset = true;
foreach (var element in t2) {
    if (!t1.Contains(element)) {
        isSubset = false;
        break;
    }
}

我做了所有的解决方案的一些基本性能分析,结果是激烈。这两种解决方案是100倍左右比。除()和.Intersect()解决方案更快,并且不使用任何额外的内存。

从@Cameron和@Neil答案我写使用相同的术语作为枚举类的扩展方法构建。

/// <summary>
/// Determines whether a sequence contains the specified elements by using the default equality comparer.
/// </summary>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <param name="source">A sequence in which to locate the values.</param>
/// <param name="values">The values to locate in the sequence.</param>
/// <returns>true if the source sequence contains elements that have the specified values; otherwise, false.</returns>
public static bool ContainsAll<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> values)
{
    return !values.Except(source).Any();
}
  

下面我们检查是否有任何存在于所述子列表元素(即t2),其不是由父列表包含(即t1)。如果没有这样的存在,那么该列表是另一个的子集

例如:

bool isSubset = !(t2.Any(x => !t1.Contains(x)));

尝试此

static bool IsSubSet<A>(A[] set, A[] toCheck) {
  return set.Length == (toCheck.Intersect(set)).Count();
}

这里的想法是,相交只会返回那些在两个数组中的值。如果在所得到的组的长度是相同的原始组这一点上,然后在“置位”的所有元素,可以在“检查”,因此“置位”是“toCheck”

的子集

请注意:如果“设置”有重复我的解决办法是行不通的。我不会改变它,因为我不想偷别人的票。

提示:我投卡梅隆的回答。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top