【问题标题】:How can I get all subsets of a set that respect the order如何获得尊重顺序的集合的所有子集
【发布时间】:2015-03-17 01:44:53
【问题描述】:

我正在寻找一个 C# 示例,该示例将在尊重顺序的同时为我提供集合的所有子集。

例如我有 A,B 并且想要:

A
B
AB
BA

请注意,出于我的目的AB != BA

解决方案应该对任何输入类型都是通用的:

List<List<T>> GetSubsets<T>(List<T> originalSet)

我遇到了一些对 AB == BA 使用按位操作的出色解决方案(例如 Generate all combinations for a list of strings),但到目前为止,我还没有找到任何可以解决上述问题的方法。

任何提示/指针将不胜感激!

【问题讨论】:

  • 找到所有子集,然后找到它们的所有排列。
  • 我认为你的问题陈述是倒退的。你要尊重秩序,而不是忽视它。
  • 你是对的雷蒙德!
  • 集合按定义是无序的

标签: c# algorithm subset


【解决方案1】:

GetPermutations() 是参考。来自https://stackoverflow.com/a/10630026/1287352

public static List<List<T>> PermutationOf<T>(HashSet<T> set)
{
    var result = new List<List<T>>();
    for (var length = 1; length <= set.Count; length++)
    {
        result.AddRange(GetPermutations<T>(set, length).Select(i => i.ToList()));
    }
    return result;
}

private static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> list, int length)
{
    if (length == 1) return list.Select(t => new T[] { t });

    return GetPermutations(list, length - 1)
        .SelectMany(t => list.Where(e => !t.Contains(e)),
        (t1, t2) => t1.Concat(new T[] { t2 }));
}

用法:

PermutationOf(new HashSet<Guid>() { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() })
PermutationOf(new HashSet<String>() { "A", "B", "C" })

结果:

A
B
C
A, B
A, C
B, A
B, C
C, A
C, B
A, B, C
A, C, B
B, A, C
B, C, A
C, A, B
C, B, A

【讨论】:

    【解决方案2】:

    你可以递归地做。

    将项目放在一个集合中,并制作一个包含子集中项目的空列表。然后调用填充列表列表的递归方法。

    在每次递归调用时,首先将您迄今为止收集的项目添加到结果列表列表中。然后对剩余的项目集合中的每个项目执行以下操作:

    1. 从剩余集合中移除该项目
    2. 将项目添加到包含部分子集的列表中
    3. 进行递归调用
    4. 从部分子集中删除项目
    5. 将该项目重新添加到剩余的集合中。

    这是一个简单的 C# 实现:

    static void CollectAll(ISet<String> remaining, IList<string> soFar, List<List<string>> all) {
        if (soFar.Count != 0) {
            all.Add(soFar.ToList());
        }
        foreach (var item in remaining.ToList()) {
            remaining.Remove(item);
            soFar.Add(item);
            CollectAll(remaining, soFar, all);
            soFar.Remove(item);
            remaining.Add(item);
        }
    }
    

    Demo.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-01
      相关资源
      最近更新 更多