Pembahagian Set: Pendekatan Rekursif
Tugas mencari semua partition set sering timbul dalam sains komputer dan matematik. Partition membahagikan set kepada subset terputus-putus, secara kolektif mengandungi semua elemen set asal.
Untuk bermula, mari kita pertimbangkan masalah yang lebih mudah: membahagikan set kepada dua subset. Untuk set elemen-n, kita boleh mewakili partition menggunakan bitmask binari. Setiap bit sepadan dengan elemen set, di mana 0 menunjukkan penempatan dalam subset pertama dan 1 menunjukkan yang kedua. Ini memastikan bahawa setiap elemen diperuntukkan tepat kepada satu subset.
Untuk mengendalikan kehadiran elemen pertama dalam subset pertama, kami hanya mempertimbangkan bitmasks dengan bit pertama ialah 0. Ini mengurangkan bilangan bitmask kepada 2 ^(n-1).
Untuk menyamaratakan pendekatan ini, kita boleh membahagikan set kepada berbilang subset secara rekursif. Kita mulakan dengan semua partition dua bahagian, kemudian bahagikan subset kedua kepada dua bahagian, kemudian subset ketiga, dan seterusnya. Proses rekursif ini menghasilkan semua partition yang mungkin.
Berikut ialah contoh pelaksanaan dalam C# yang menjana semua partition untuk tatasusunan tertentu:
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()); } } } }
Memanggil GetAllPartitions dengan tatasusunan elemen menjana semua partition yang mungkin untuk set itu.
Atas ialah kandungan terperinci Bagaimanakah Kami Boleh Menjana Semua Pembahagian Set secara Rekursif?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!