c# - 棘手的算法......在嵌套的 HashSets 中找到子集的多个组合?

标签 c# algorithm hashset

我遇到一个问题,我必须在嵌套哈希集中找到子集的多个组合。基本上我有一个“主”嵌套 HashSet,并且从“可能”嵌套 HashSet 的集合中我必须以编程方式找到可能是“主”的同时子集的“可能”。

假设我有以下内容:

            var master = new HashSet<HashSet<string>>(new HashSet<string>[] {
                        new HashSet<string>( new string[] { "A", "B", "C"}),
                        new HashSet<string>( new string[] { "D", "E"}),
                        new HashSet<string>( new string[] { "F"})
                    }
                ); 
            var possible1  = new HashSet<HashSet<string>>(new HashSet<string>[] {
                        new HashSet<string>( new string[] { "A", "B", "C"}),
                        new HashSet<string>( new string[] { "F"})
                    }
                 );
            var possible2 = new HashSet<HashSet<string>>(new HashSet<string>[] {
                        new HashSet<string>( new string[] { "D", "E"})
                    }
                 ); 
            var possible3 = new HashSet<HashSet<string>>(new HashSet<string>[] {
                        new HashSet<string>( new string[] { "F"})
                    }
                 ); 
            var possible4 = new HashSet<HashSet<string>>(new HashSet<string>[] {
                        new HashSet<string>( new string[] { "X", "Y", "Z"})
                    }
                ); 
            var possible5 = new HashSet<HashSet<string>>(new HashSet<string>[] {
                        new HashSet<string>( new string[] { "A", "B" }),
                        new HashSet<string>( new string[] { "D", "E"})
                    }
                ); 

我的算法应该得到的输出应该如下所示:

所有可能的组合子集:

possible1 and possible2
possible3 and possible5
possible2 and possible3
possible1
possible2
possible3
possible5

我正在尝试找出解决此问题的最佳方法。当然,还有蛮力选项,但如果可以的话,我会尽量避免这种情况。

我只希望我的问题足够清楚。

编辑

为了进一步阐述什么是子集,这里有一些例子,给定主 {{"A","B","C"},{"C","D","E",F"},{"X","Y","Z"}}:

  • {{"A","B"}{"C","D"}} 将是
  • 的子集
  • {{"A","B","C"},{"X","Y"}} 是一个子集
  • {{"A","B"},{"A","B"}} 不会是子集
  • {{"A","B","C","D"}} 不会是子集
  • {{"A","B","C"},{"C","D","X"}} 不是子集

基本上每个子集都需要是母版中相应子集的子集。

最佳答案

使用暴力破解:

public static int IsCsInMaster(HashSet<string> childSubset, List<HashSet<string>> master, int startIndex)
{
    for (int i = startIndex; i < master.Count; i++)
        if (childSubset.IsSubsetOf(master[i])) return i;

    return -1;
}

public static bool IsChildInMaster(List<HashSet<string>> child, List<HashSet<string>> master)
{
    foreach (var childSubset in child) if (IsCsInMaster(childSubset, master, 0) == -1) return false;

    return true;
}

public static bool IsChildInMasterMulti(List<HashSet<string>> child, List<HashSet<string>> master)
{
    Dictionary<int, int> subsetChecker = new Dictionary<int, int>();
    List<IEnumerable<int>> multiMatches = new List<IEnumerable<int>>();
    int subsetIndex;

    // Check for matching subsets.
    for (int i = 0; i < child.Count; i++)
    {
        subsetIndex = 0;
        List<int> indexes = new List<int>();

        while ((subsetIndex = IsCsInMaster(child[i], master, subsetIndex)) != -1)
        {
            indexes.Add(subsetIndex++);
        }

        if (indexes.Count == 1)
        {
            subsetIndex = indexes[0];
            if (subsetChecker.ContainsKey(subsetIndex)) return false;
            else subsetChecker[subsetIndex] = subsetIndex;
        }
        else
        {
            multiMatches.Add(indexes);
        }
    }

    /*** Check for multi-matching subsets. ***/ //got lazy ;)
    var union = multiMatches.Aggregate((aggr, indexes) => aggr.Union(indexes));

    // Filter the union so only unmatched subset indexes remain.
    List<int> filteredUion = new List<int>();
    foreach (int index in union)
    {
        if (!subsetChecker.ContainsKey(index)) filteredUion.Add(index);
    }

    return (filteredUion.Count >= multiMatches.Count);
}

在代码中:

IsChildInMasterMulti(possible2, master)

不过,该代码不处理 {{"A","B"},{"A","B"}} 的情况。这要困难得多(递归地标记 master 中使用的子集,甚至可能是单个元素)。

Edit2:第三种方法也处理 {{"A","B"},{"A","B"}} 情况(并且更多)。

关于c# - 棘手的算法......在嵌套的 HashSets 中找到子集的多个组合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3189219/

相关文章:

algorithm - 字符串构建算法的时间复杂度

java - 合并包含集合的映射会抛出 UnsupportedOperationException

.net - HashSet<T> 与 Dictionary<K, V> 相对于查找项目是否存在的搜索时间

algorithm - 算法的时间复杂度

c# - 将方法调用变成可观察事件,好主意吗?

c# - Blend 不调用 DesignTimeBootstrapper

确定网格单元格上的 Blob 重叠百分比的算法

c++ - 如何实现类似电话簿的应用程序

c# - 等待动态创建的任务直到它们完成

c# - 动态写入图像