Rumah > pembangunan bahagian belakang > C++ > Bagaimanakah Kami Boleh Menjana Semua Pembahagian Set secara Rekursif?

Bagaimanakah Kami Boleh Menjana Semua Pembahagian Set secara Rekursif?

Mary-Kate Olsen
Lepaskan: 2024-12-27 04:14:10
asal
229 orang telah melayarinya

How Can We Recursively Generate All Partitions of a Set?

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());
            }
        }
    }
}
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan