2012-10-22 5 views
8

私は、入力配列のすべての可能なサブセット(空の要素を持たないパワーセット)を含む、配列の入力と戻りの配列で配列をとる関数を記述しようとしています。たとえば、入力の場合:[1, 2, 3]の場合、結果は[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]になります。デルファイの配列のパワーセット

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

しかし、私はDelphiでそれを実現するために探しています:

この関数はPythonで仕事をしていません。この方法でこれを達成することは可能ですか、他に何かを探すべきですか?

+1

。 –

+2

私の答えはここに役立ちます:http://stackoverflow.com/questions/8316479/combination-without-repetition-of-n-elements-without-use-for-to-do –

答えて

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

私はこの方法を与え、それはちょうど働いた適応!ありがとう、あなたは最高です。 – maciejjo

+0

TotalCombinations:= 2 shl(TotalItems - 1); TotalCombinations:= 1 shl TotalItemsでなければなりません。 –

+0

@DavidHeffernan同じ結果ですが、もう少し論理的です。それを変更しました。 – GolezTrol

2

私の他の答えは、私はあなたがジェネリックを使用することができ、それはより汎用的にするためにデルファイ2007年で、必要なときに、私はしばらく前に作成したコードの一部です。今私は実際にジェネリックを使っていませんが、これはこのように動作するようです。構文を確認するには、私はpeek hereを持っていたことを認めなければなりません。簡単な方法があれば、他の誰かがそれを投稿できることを願っています。

入力パラメータの名前を除いて、コードは実際にはほとんど変更されていません。 (!イェーイ、ジェネリック医薬品)

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; 

そして、このように使用:これを行うには確かに可能である(ただし、コードはおそらく、Delphiでそれ簡単ではありません)

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]); 
関連する問題