2012-10-22 21 views
8

Tüm olası giriş alt kümelerini (boş öğe olmadan güç kümesi) içeren dizilerin giriş ve dönüş dizilerinde bir dizi alacaktır. Örneğin: [1, 2, 3] girişi için sonuç [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]] olacaktır.Delphi'de bir dizinin güç kümesi

def list_powerset(lst): 
    result = [[]] 
    for x in lst: 
     result += [subset + [x] for subset in result] 
    result.pop(0) 
    return result 

Ama Delphi bunun uygulanması için arıyorum:

Bu fonksiyon Python işi yapar. Bu şekilde gerçekleştirmek mümkün mü yoksa başka bir şey mi aramalıyım?

+1

O (ama kod muhtemelen Delphi bu kısa olmayacak) bunu yapmak kesinlikle mümkündür. –

+2

Cevabım burada yardımcı olmalıdır: http://stackoverflow.com/questions/8316479/combination-without-repetition-of-n-elements-without-use-for-to-do –

cevap

6
type 
    TIdArray = array of Integer; 
    TPowerSet = array of TIdArray; 

function PowerSet(Ids: TIdArray): TPowerSet; 
// Implementation loosely based on the explanation on 
// http://www.mathsisfun.com/sets/power-set.html 
var 
    TotalCombinations: Integer; 
    TotalItems: Integer; 
    Combination: Integer; 
    SourceItem: Integer; 
    ResultItem: Integer; 
    Bit, Bits: Integer; 
begin 
    TotalItems := Length(Ids); 

    // Total number of combination for array of n items = 2^n. 
    TotalCombinations := 1 shl TotalItems; 

    SetLength(Result, TotalCombinations); 

    for Combination := 0 to TotalCombinations - 1 do 
    begin 
    // The Combination variable contains a bitmask that tells us which items 
    // to take from the array to construct the current combination. 
    // Disadvantage is that because of this method, the input array may contain 
    // at most 32 items. 

    // Count the number of bits set in Combination. This is the number of items 
    // we need to allocate for this combination. 
    Bits := 0; 
    for Bit := 0 to TotalItems - 1 do 
     if Combination and (1 shl Bit) <> 0 then 
     Inc(Bits); 

    // Allocate the items. 
    SetLength(Result[Combination], Bits); 

    // Copy the right items to the current result item. 
    ResultItem := 0; 

    for SourceItem := 0 to TotalItems - 1 do 
     if Combination and (1 shl SourceItem) <> 0 then 
     begin 
     Result[Combination][ResultItem] := Ids[SourceItem]; 
     Inc(ResultItem); 
     end; 
    end; 

end; 
+1

Bu yönteme bir çekim yaptım ve adaptasyon sadece çalıştı! Teşekkürler, en iyisisin. – maciejjo

+0

Toplam Oluşan: = 2 shl (TotalItems - 1); Toplam Kombinasyonlar olmalıdır: = 1 shl TotalItems; –

+0

@DavidHeffernan Aynı sonuç, ama biraz daha mantıklı. Değiştirdi. – GolezTrol

2

Benim diğer cevabı ben daha genel, sen generics kullanabilir hale getirmek için Delphi 2007'de de gerektiğinde bir süre önce oluşturulan bir kod parçasıdır. Şimdi daha önce jenerik kullanmamıştım, ama bu şekilde çalışıyor gibi görünüyor. Ben sözdizimi kontrol etmek için peek here vardı zorunda itiraf etmeliyim. Daha kolay bir yol varsa, umarım başka biri gönderebilir.

Kod, aslında giriş parametresinin adı dışında pratikte değiştirilmemiş. (Yay, jenerik!) Böyle

type 
    TGenericArray<T> = array of T; 
    TGenericPowerSet<T> = array of array of T; 

    TPowerSet<T> = class(TObject) 
    public 
    class function Get(a: TGenericArray<T>): TGenericPowerSet<T>; 
    end; 

class function TPowerSet<T>.Get(a: TGenericArray<T>): TGenericPowerSet<T>; 
var 
    TotalCombinations: Integer; 
    TotalItems: Integer; 
    Combination: Integer; 
    SourceItem: Integer; 
    ResultItemIncluded: Integer; 
    Bit, Bits: Integer; 
begin 
    TotalItems := Length(a); 

    // Total number of combination for array of n items = 2^n. 
    TotalCombinations := 1 shl TotalItems; 

    SetLength(Result, TotalCombinations); 

    for Combination := 0 to TotalCombinations - 1 do 
    begin 
    // The Combination variable contains a bitmask that tells us which items 
    // to take from the array to construct the current combination. 
    // Disadvantage is that because of this method, the input array may contain 
    // at most 32 items. 

    // Count the number of bits set in Combination. This is the number of items 
    // we need to allocate for this combination. 
    Bits := 0; 
    for Bit := 0 to TotalItems - 1 do 
     if Combination and (1 shl Bit) <> 0 then 
     Inc(Bits); 

    // Allocate the items. 
    SetLength(Result[Combination], Bits); 

    // Copy the right items to the current result item. 
    ResultItemIncluded := 0; 

    for SourceItem := 0 to TotalItems - 1 do 
     if Combination and (1 shl SourceItem) <> 0 then 
     begin 
     Result[Combination][ResultItemIncluded] := a[SourceItem]; 
     Inc(ResultItemIncluded); 
     end; 
    end; 

end; 

Ve kullanın:

var 
    p: TPowerSet<String>; 
    a: TGenericArray<String>; 
    r: TGenericPowerSet<String>; 
begin 
    SetLength(a, 2); 
    a[0] := 'aaa'; 
    a[1] := 'bbb'; 
    r := p.Get(a); 

    ShowMessage(IntToStr(Length(r))); 
    ShowMessage(r[1][0]);