Heim > Backend-Entwicklung > C++ > Wie können wir alle Partitionen einer Menge rekursiv generieren?

Wie können wir alle Partitionen einer Menge rekursiv generieren?

Mary-Kate Olsen
Freigeben: 2024-12-27 04:14:10
Original
270 Leute haben es durchsucht

How Can We Recursively Generate All Partitions of a Set?

Partitionieren einer Menge: Ein rekursiver Ansatz

Die Aufgabe, alle Partitionen einer Menge zu finden, stellt sich häufig in der Informatik und Mathematik. Eine Partition unterteilt eine Menge in disjunkte Teilmengen, die zusammen alle Elemente der ursprünglichen Menge enthalten.

Betrachten wir zunächst ein einfacheres Problem: die Aufteilung einer Menge in zwei Teilmengen. Für eine n-elementige Menge können wir eine Partition mithilfe einer binären Bitmaske darstellen. Jedes Bit entspricht einem Element der Menge, wobei eine 0 die Platzierung in der ersten Teilmenge und eine 1 die zweite angibt. Dadurch wird sichergestellt, dass jedes Element genau einer Teilmenge zugeordnet ist.

Um das Vorhandensein des ersten Elements in der ersten Teilmenge zu handhaben, berücksichtigen wir nur Bitmasken, bei denen das erste Bit 0 ist. Dadurch wird die Anzahl der Bitmasken auf 2 reduziert ^(n-1).

Um diesen Ansatz zu verallgemeinern, können wir eine Menge rekursiv in mehrere Teilmengen unterteilen. Wir beginnen mit allen zweiteiligen Partitionen, teilen dann die zweite Teilmenge in zwei Teile auf, dann die dritte Teilmenge und so weiter. Dieser rekursive Prozess erzeugt alle möglichen Partitionen.

Hier ist eine Beispielimplementierung in C#, die alle Partitionen für ein bestimmtes Array generiert:

using System;
using System.Collections.Generic;

namespace Partitioning
{
    public static class Program
    {
        public static IEnumerable<T[][]> GetAllPartitions<T>(T[] elements)
        {
            return GetAllPartitions(new T[][] { }, elements);
        }

        private static IEnumerable<T[][]> GetAllPartitions<T>(T[][] fixedParts, T[] suffixElements)
        {
            // Trivial partition: fixed parts followed by remaining elements as one block
            yield return fixedParts.Concat(new[] { suffixElements }).ToArray();

            // Get all two-part partitions of suffix elements and subdivide recursively
            var suffixPartitions = GetTuplePartitions(suffixElements);

            foreach (Tuple<T[], T[]> suffixPartition in suffixPartitions)
            {
                var recursivePartitions = GetAllPartitions(fixedParts.Concat(new[] { suffixPartition.Item1 }).ToArray(), suffixPartition.Item2);
                foreach (T[][] partition in recursivePartitions)
                {
                    yield return partition;
                }
            }
        }

        private static IEnumerable<Tuple<T[], T[]>> GetTuplePartitions<T>(T[] elements)
        {
            if (elements.Length < 2)
                yield break;

            for (int pattern = 1; pattern < 1 << (elements.Length - 1); pattern++)
            {
                List<T>[] resultSets = { new List<T> { elements[0] }, new List<T>() };

                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());
            }
        }
    }
}
Nach dem Login kopieren

Der Aufruf von GetAllPartitions mit einem Array von Elementen generiert alle möglichen Partitionen für dieses Set.

Das obige ist der detaillierte Inhalt vonWie können wir alle Partitionen einer Menge rekursiv generieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage