2011-11-18 12 views
5

में चुने गए आइटमों से सभी संयोजन उत्पन्न करना मुझे यह पता लगाना है कि कोई विशेष एल्गोरिदम पहले से मौजूद है या नहीं। मैं इसे किसी एप्लिकेशन में उपयोग करना चाहता हूं, लेकिन मैंने यह भी देखा है कि यह कई Project Euler समस्याओं में भी आया है।एल्गोरिदम - अनुक्रम

मैं एक विशिष्ट प्रकार के क्रमपरिवर्तन/आउटपुट सेट की गणना करने के लिए देख रहा हूं, जहां अगला आइटम केवल निम्न सेट में विकल्पों के सीमित सेट से होना चाहिए।

उदाहरण के लिए, मैं 3 सरणियों

$a1 = array("a", "b", "c"); 
$a2 = array("d", "e", "f"); 
$a3 = array("g", "h", "i"); 

मैं एक दृश्य प्रत्येक सरणी, आदेश में चुना से अधिकतम 1 तत्व से युक्त की सभी संभावनाओं को उत्पन्न करने के लिए देख रहा हूँ मिल गया है कहना। यही कारण है कि आउटपुट के रूप में कहने के लिए है, मैं देखना चाहते हैं:

adg aeg afg 
adh aeh afh 
adi aei afi 

bdg beg bfg 
bdh beh bfh 
bdi bei bfi 

cdg ceg cfg 
cdh ceh cfh 
cdi cei cfi 

या तो PHP या जावास्क्रिप्ट में एल्गोरिथ्म को लागू करने के देख रहे हैं। संक्षेप में यह तत्वों की परिवर्तनीय संख्या वाले सरणी की एक चर संख्या से गुज़र जाएगा, और अनुक्रमिक क्रम में होने वाले अनुक्रमों की सभी संभावनाओं को आउटपुट करेगा।

क्या यह अस्तित्व में है?

यदि हां, तो इसे क्या कहा जाता है? तकनीकी रूप से यह एक क्रमपरिवर्तन या संयोजन से संयोजन है जो मैं दोनों के बारे में जानता हूं।

संपादित करें: डैनियल फिशर मुझे सूचित किया है कि यह एक कार्तीय उत्पाद है, यहाँ एक कार्यान्वयन taken from the PHP website है:

function array_cartesian_product($arrays) 
{ 
    $result = array(); 
    $arrays = array_values($arrays); 
    $sizeIn = sizeof($arrays); 
    $size = $sizeIn > 0 ? 1 : 0; 
    foreach ($arrays as $array) 
     $size = $size * sizeof($array); 
    for ($i = 0; $i < $size; $i ++) 
    { 
     $result[$i] = array(); 
     for ($j = 0; $j < $sizeIn; $j ++) 
      array_push($result[$i], current($arrays[$j])); 
     for ($j = ($sizeIn -1); $j >= 0; $j --) 
     { 
      if (next($arrays[$j])) 
       break; 
      elseif (isset ($arrays[$j])) 
       reset($arrays[$j]); 
     } 
    } 
    return $result; 
} 

उत्तर

2

यदि वास्तव में एक आइटम प्रत्येक सूची/सरणी से चुन लिया जाता है यह एक कार्तीय उत्पाद है, और अधिक स्पष्ट एक कार्टेशियन उत्पाद के तत्वों की सूची। सूचियों के लिए, यह हास्केल के मानक पुस्तकालय में है:

Prelude> sequence ["abc","def","ghi"] 
["adg","adh","adi","aeg","aeh","aei","afg","afh","afi","bdg","bdh","bdi","beg","beh" 
,"bei","bfg","bfh","bfi","cdg","cdh","cdi","ceg","ceh","cei","cfg","cfh","cfi"] 

मैं PHP या जावास्क्रिप्ट के लिए लगता है, आप इसे अपने आप को कोड करने के लिए किया है।

0

आप लूप में तत्वों के माध्यम से जा सकते हैं। खासकर यदि आप बहुत लंबे सरणियों के सरणियों के बहुत सारे है, हालांकि यह बहुत धीमी है कि

var ret = []; 
for (var i=0; i<a1.length; i++) { 
    for (var j=0; j<a2.length; j++) { 
    for (var k=0; k<a3.length; k++) { 
     ret.push([a1[i], a2[j], a3[k]]); 
    } 
    } 
} 
// do stuff with ret 

ध्यान दें, उदाहरण के लिए, यदि आप अपने मामले के लिए निम्न कर सकते हैं। प्रोजेक्ट यूलर के लिए, आमतौर पर कुछ अन्य अंतर्दृष्टि होती है जिसका उपयोग आप सब कुछ समझाए जाने के बजाय कर सकते हैं।

+0

ठीक है, हालांकि मैं अवधारणा को सारणीबद्ध करना चाहता हूं ताकि मैं इसे एक चरणीय संख्या के सरणी के विरुद्ध चला सकूं। – barfoon

0

मुझे लगता है कि आप सही हैं कि यह न तो क्रमपरिवर्तन है और न ही संयोजन है क्योंकि स्ट्रिंग-लम्बाई आपके मामले में तय की गई है। जावा [7] का उपयोग क्षमा करें, लेकिन यह वह है जिसे मैं वर्तमान में सबसे अच्छा जानता हूं।

public abstract class AFixedPermutation { 
    private char[][] fields; 
    private StringBuilder sb = new StringBuilder(); 
    private int[] callvec; 
    private int maxDepth; 

    public FixedPermutation(char[][] fields) { 
    this.fields = fields; 

    callvec = new int[fields.length]; 
    for (int i = 0; i < fields.length; i++) callvec[i] = 0; 
    maxDepth = callvec.length - 1; 
    recurse(0); 
    } 

    protected abstract emit(String s); 

    private void recurse(int depth) { 
    for (int i = 0; i < fields[depth].length; i++) { 
     callvec[depth] = i; 
     if (depth == maxDepth) { apply(); } 
     else {recurse(depth + 1); } 
    } 
    } 

    private void apply() { 
     sb.setLength(0); 
     for (int i = 0; i < callvec.length; i++) { 
     sb.append(fields[i][callvec[i]]); 
     } 
     emit(sb.toString()); 
    } 
} 
0

में मेथेमेटिका इस देशी रूप Tuples के रूप में कार्यान्वित किया जाता है।

Tuples[{{a, b, c}, {d, e, f}, {g, h, i}}] 
{{a, d, g}, {a, d, h}, {a, d, i}, {a, e, g}, {a, e, h}, {a, e, i}, 
{a, f, g}, {a, f, h}, {a, f, i}, {b, d, g}, {b, d, h}, {b, d, i}, 
{b, e, g}, {b, e, h}, {b, e, i}, {b, f, g}, {b, f, h}, {b, f, i}, 
{c, d, g}, {c, d, h}, {c, d, i}, {c, e, g}, {c, e, h}, {c, e, i}, 
{c, f, g}, {c, f, h}, {c, f, i}}

यह भी Outer (सामान्यीकृत बाहरी उत्पाद) के साथ किया जा सकता है:

Outer[List, {a, b, c}, {d, e, f}, {g, h, i}] 

या यात्रा के साथ (Table):

Table[{x, y, z}, 
{x, {a, b, c}}, 
{y, {d, e, f}}, 
{z, {g, h, i}} 
] 

या प्रत्यावर्तन के साथ:

sets[{}, c__] := {{c}} 
sets[{x_, r___}, c___] := Join @@ (sets[{r}, c, #] & /@ x) 

sets[{{a, b, c}, {d, e, f}, {g, h, i}}] 
संबंधित मुद्दे