<tfoot id='vvHx7'></tfoot>

      <legend id='vvHx7'><style id='vvHx7'><dir id='vvHx7'><q id='vvHx7'></q></dir></style></legend>

        • <bdo id='vvHx7'></bdo><ul id='vvHx7'></ul>

        <small id='vvHx7'></small><noframes id='vvHx7'>

        <i id='vvHx7'><tr id='vvHx7'><dt id='vvHx7'><q id='vvHx7'><span id='vvHx7'><b id='vvHx7'><form id='vvHx7'><ins id='vvHx7'></ins><ul id='vvHx7'></ul><sub id='vvHx7'></sub></form><legend id='vvHx7'></legend><bdo id='vvHx7'><pre id='vvHx7'><center id='vvHx7'></center></pre></bdo></b><th id='vvHx7'></th></span></q></dt></tr></i><div id='vvHx7'><tfoot id='vvHx7'></tfoot><dl id='vvHx7'><fieldset id='vvHx7'></fieldset></dl></div>

        如何找到集合的所有分区

        How to find all partitions of a set(如何找到集合的所有分区)
          • <bdo id='UbcF4'></bdo><ul id='UbcF4'></ul>
          • <i id='UbcF4'><tr id='UbcF4'><dt id='UbcF4'><q id='UbcF4'><span id='UbcF4'><b id='UbcF4'><form id='UbcF4'><ins id='UbcF4'></ins><ul id='UbcF4'></ul><sub id='UbcF4'></sub></form><legend id='UbcF4'></legend><bdo id='UbcF4'><pre id='UbcF4'><center id='UbcF4'></center></pre></bdo></b><th id='UbcF4'></th></span></q></dt></tr></i><div id='UbcF4'><tfoot id='UbcF4'></tfoot><dl id='UbcF4'><fieldset id='UbcF4'></fieldset></dl></div>

            <small id='UbcF4'></small><noframes id='UbcF4'>

            <tfoot id='UbcF4'></tfoot><legend id='UbcF4'><style id='UbcF4'><dir id='UbcF4'><q id='UbcF4'></q></dir></style></legend>

                <tbody id='UbcF4'></tbody>

                1. 本文介绍了如何找到集合的所有分区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我有一组不同的价值观.我正在寻找一种方法来生成该集合的所有分区,即将集合划分为子集的所有可能方式.

                  I have a set of distinct values. I am looking for a way to generate all partitions of this set, i.e. all possible ways of dividing the set into subsets.

                  例如,集合 {1, 2, 3} 具有以下分区:

                  For instance, the set {1, 2, 3} has the following partitions:

                  { {1}, {2}, {3} },
                  { {1, 2}, {3} },
                  { {1, 3}, {2} },
                  { {1}, {2, 3} },
                  { {1, 2, 3} }.
                  

                  由于这些是数学意义上的集合,因此顺序无关紧要.例如,{1, 2}, {3}{3}, {2, 1} 相同,不应是单独的结果.

                  As these are sets in the mathematical sense, order is irrelevant. For instance, {1, 2}, {3} is the same as {3}, {2, 1} and should not be a separate result.

                  可以在 Wikipedia 上找到集分区的详细定义.

                  A thorough definition of set partitions can be found on Wikipedia.

                  推荐答案

                  我找到了一个简单的递归解决方案.

                  I've found a straightforward recursive solution.

                  首先,让我们解决一个更简单的问题:如何找到恰好由两部分组成的所有分区.对于一个 n 元素集,我们可以从 0 到 (2^n)-1 计算一个 int.这将创建每个 n 位模式,每个位对应于一个输入元素.如果该位为 0,我们将元素放在第一部分;如果为 1,则元素放置在第二部分.这留下了一个问题:对于每个分区,我们将得到一个重复的结果,其中两个部分被交换.为了解决这个问题,我们总是将第一个元素放入第一部分.然后我们只通过从 0 到 (2^(n-1))-1 的计数来分配剩余的 n-1 个元素.

                  First, let's solve a simpler problem: how to find all partitions consisting of exactly two parts. For an n-element set, we can count an int from 0 to (2^n)-1. This creates every n-bit pattern, with each bit corresponding to one input element. If the bit is 0, we place the element in the first part; if it is 1, the element is placed in the second part. This leaves one problem: For each partition, we'll get a duplicate result where the two parts are swapped. To remedy this, we'll always place the first element into the first part. We then only distribute the remaining n-1 elements by counting from 0 to (2^(n-1))-1.

                  现在我们可以将一个集合分成两部分,我们可以编写一个递归函数来解决剩下的问题.该函数从原始集合开始并找到所有两部分分区.对于这些分区中的每一个,它递归地找到将第二部分分成两部分的所有方法,从而产生所有三部分分区.然后它划分每个分区的最后一部分以生成所有四部分分区,依此类推.

                  Now that we can partition a set into two parts, we can write a recursive function that solves the rest of the problem. The function starts off with the original set and finds all two-part-partitions. For each of these partitions, it recursively finds all ways to partition the second part into two parts, yielding all three-part partitions. It then divides the last part of each of these partitions to generate all four-part partitions, and so on.

                  以下是 C# 中的实现.调用

                  The following is an implementation in C#. Calling

                  Partitioning.GetAllPartitions(new[] { 1, 2, 3, 4 })
                  

                  产量

                  { {1, 2, 3, 4} },
                  { {1, 3, 4}, {2} },
                  { {1, 2, 4}, {3} },
                  { {1, 4}, {2, 3} },
                  { {1, 4}, {2}, {3} },
                  { {1, 2, 3}, {4} },
                  { {1, 3}, {2, 4} },
                  { {1, 3}, {2}, {4} },
                  { {1, 2}, {3, 4} },
                  { {1, 2}, {3}, {4} },
                  { {1}, {2, 3, 4} },
                  { {1}, {2, 4}, {3} },
                  { {1}, {2, 3}, {4} },
                  { {1}, {2}, {3, 4} },
                  { {1}, {2}, {3}, {4} }.
                  

                  using System;
                  using System.Collections.Generic;
                  using System.Linq;
                  
                  namespace PartitionTest {
                      public static class Partitioning {
                          public static IEnumerable<T[][]> GetAllPartitions<T>(T[] elements) {
                              return GetAllPartitions(new T[][]{}, elements);
                          }
                  
                          private static IEnumerable<T[][]> GetAllPartitions<T>(
                              T[][] fixedParts, T[] suffixElements)
                          {
                              // A trivial partition consists of the fixed parts
                              // followed by all suffix elements as one block
                              yield return fixedParts.Concat(new[] { suffixElements }).ToArray();
                  
                              // Get all two-group-partitions of the suffix elements
                              // and sub-divide them recursively
                              var suffixPartitions = GetTuplePartitions(suffixElements);
                              foreach (Tuple<T[], T[]> suffixPartition in suffixPartitions) {
                                  var subPartitions = GetAllPartitions(
                                      fixedParts.Concat(new[] { suffixPartition.Item1 }).ToArray(),
                                      suffixPartition.Item2);
                                  foreach (var subPartition in subPartitions) {
                                      yield return subPartition;
                                  }
                              }
                          }
                  
                          private static IEnumerable<Tuple<T[], T[]>> GetTuplePartitions<T>(
                              T[] elements)
                          {
                              // No result if less than 2 elements
                              if (elements.Length < 2) yield break;
                  
                              // Generate all 2-part partitions
                              for (int pattern = 1; pattern < 1 << (elements.Length - 1); pattern++) {
                                  // Create the two result sets and
                                  // assign the first element to the first set
                                  List<T>[] resultSets = {
                                      new List<T> { elements[0] }, new List<T>() };
                                  // Distribute the remaining elements
                                  for (int index = 1; index < elements.Length; index++) {
                                      resultSets[(pattern >> (index - 1)) & 1].Add(elements[index]);
                                  }
                  
                                  yield return Tuple.Create(
                                      resultSets[0].ToArray(), resultSets[1].ToArray());
                              }
                          }
                      }
                  }
                  

                  这篇关于如何找到集合的所有分区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Adding and removing users from Active Directory groups in .NET(在 .NET 中的 Active Directory 组中添加和删除用户)
                  set equality in linq(在 linq 中设置相等)
                  HashSet conversion to List(HashSet 转换为 List)
                  How to set timeout for webBrowser navigate event(如何为 webBrowser 导航事件设置超时)
                  Test whether two IEnumerablelt;Tgt; have the same values with the same frequencies(测试两个IEnumerablelt;Tgt;具有相同频率的相同值)
                  How do you determine if two HashSets are equal (by value, not by reference)?(您如何确定两个 HashSet 是否相等(按值,而不是按引用)?)
                  • <bdo id='1KV4e'></bdo><ul id='1KV4e'></ul>

                      <small id='1KV4e'></small><noframes id='1KV4e'>

                    • <legend id='1KV4e'><style id='1KV4e'><dir id='1KV4e'><q id='1KV4e'></q></dir></style></legend>
                      • <i id='1KV4e'><tr id='1KV4e'><dt id='1KV4e'><q id='1KV4e'><span id='1KV4e'><b id='1KV4e'><form id='1KV4e'><ins id='1KV4e'></ins><ul id='1KV4e'></ul><sub id='1KV4e'></sub></form><legend id='1KV4e'></legend><bdo id='1KV4e'><pre id='1KV4e'><center id='1KV4e'></center></pre></bdo></b><th id='1KV4e'></th></span></q></dt></tr></i><div id='1KV4e'><tfoot id='1KV4e'></tfoot><dl id='1KV4e'><fieldset id='1KV4e'></fieldset></dl></div>

                        <tfoot id='1KV4e'></tfoot>

                              <tbody id='1KV4e'></tbody>