2012-10-22 22 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 

लेकिन मैं डेल्फी में यह के कार्यान्वयन के लिए देख रहा हूँ। क्या यह इस तरह से पूरा करना संभव है या मुझे कुछ और देखना चाहिए?

+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

कुलकंपनीकरण: = 2 शेल (कुलतम - 1); कुल कॉम्बिनेशन होना चाहिए: = 1 श्लोक कुल इटम्स; –

+0

@ डेविड हेफरनन वही परिणाम, लेकिन थोड़ा और तार्किक। उसे बदल दिया। – 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; 

और इस तरह का उपयोग करें:

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]);