> 백엔드 개발 > C++ > 세트의 모든 파티션을 어떻게 반복적으로 생성할 수 있습니까?

세트의 모든 파티션을 어떻게 반복적으로 생성할 수 있습니까?

Mary-Kate Olsen
풀어 주다: 2024-12-27 04:14:10
원래의
224명이 탐색했습니다.

How Can We Recursively Generate All Partitions of a Set?

세트 분할: 재귀적 접근 방식

세트의 모든 파티션을 찾는 작업은 컴퓨터 과학 및 수학에서 자주 발생합니다. 파티션은 집합을 서로 분리된 하위 집합으로 나누고 원래 집합의 모든 요소를 ​​집합적으로 포함합니다.

시작하려면 집합을 두 개의 하위 집합으로 나누는 더 간단한 문제를 생각해 보겠습니다. n개 요소 집합의 경우 바이너리 비트마스크를 사용하여 파티션을 나타낼 수 있습니다. 각 비트는 집합의 요소에 해당합니다. 여기서 0은 첫 번째 하위 집합의 배치를 나타내고 1은 두 번째 하위 집합을 나타냅니다. 이렇게 하면 각 요소가 정확히 하나의 하위 집합에 할당됩니다.

첫 번째 하위 집합의 첫 번째 요소 존재를 처리하기 위해 첫 번째 비트가 0인 비트마스크만 고려합니다. 이렇게 하면 비트마스크 수가 2로 줄어듭니다. ^(n-1).

이 접근 방식을 일반화하기 위해 집합을 반복적으로 여러 하위 집합으로 분할할 수 있습니다. 두 부분으로 구성된 파티션으로 시작한 다음 두 번째 하위 집합을 두 부분으로 나눈 다음 세 번째 하위 집합 등으로 나눕니다. 이 재귀 프로세스는 가능한 모든 파티션을 생성합니다.

다음은 지정된 배열에 대한 모든 파티션을 생성하는 C# 구현의 예입니다.

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());
            }
        }
    }
}
로그인 후 복사

요소 배열을 사용하여 GetAllPartitions를 호출하면 가능한 모든 파티션이 생성됩니다. 그 세트를 위해.

위 내용은 세트의 모든 파티션을 어떻게 반복적으로 생성할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿