2013-02-18 27 views
7

के कई लॉजिकल "शाखाओं" में विभाजित और जुड़ें, मुझे पता है कि क्रमपरिवर्तन सूची के बारे में SO पर समान रूप से शब्द वाले प्रश्न हैं, लेकिन वे वास्तव में जो कुछ भी ढूंढ रहे हैं उसे बिल्कुल संबोधित नहीं करते हैं। मुझे पता है कि ऐसा करने का एक तरीका है लेकिन मैं एक खाली चित्र खींच रहा हूं।स्ट्रिंग डेटा

Col1|Col2|Col3|Col4|Col5|Col6 
a|b,c,d|e|f|g,h|i 
. . . 

अब यहाँ चाल है:: मैं एक फ्लैट फ़ाइल है कि इस प्रारूप जैसा दिखता है मैं इन पंक्तियों, जहां पंक्ति में एक अल्पविराम से अलग किए संभावित मान का प्रतिनिधित्व करता है के सभी संभव क्रमपरिवर्तन की एक सूची बनाना चाहते हैं।

IEnumerable<string> row = new string[] { "a", "b,c,d", "e", "f", "g,h", "i" }; 
IEnumerable<string> permutations = GetPermutations(row, delimiter: "/"); 

इस स्ट्रिंग डेटा के निम्नलिखित संग्रह उत्पन्न करनी चाहिए: उदाहरण के लिए, मैं करने के लिए आपके IEnumerable<string> जैसे पंक्तियों को ऊपर का प्रतिनिधित्व करने में सक्षम होना चाहिए मेरे लिए

a/b/e/f/g/i 
a/b/e/f/h/i 
a/c/e/f/g/i 
a/c/e/f/h/i 
a/d/e/f/g/i 
a/d/e/f/h/i 

यह की तरह लगता है होगा खूबसूरती से एक पुनरावर्ती विधि में फिट है, लेकिन स्पष्ट रूप से मेरे पास सोमवार का एक बुरा मामला है और मैं अपने मस्तिष्क को इस बात से कैसे लपेट सकता हूं कि इसे कैसे पहुंचाया जाए। कुछ मदद की सराहना की जाएगी। GetPermutations(IEnumerable<string>, string) क्या दिखना चाहिए?

+0

क्या यह होमवर्क है? –

+0

हां नहीं, मैं 40 तक पहुंच रहा हूं, लेकिन पूछने के लिए धन्यवाद। नहीं यह एक विज्ञापन आवेदन के लिए है। मैं उन पृष्ठों के लिए कॉन्फ़िगरेशन फ़ाइल पढ़ने की कोशिश कर रहा हूं जो विशिष्ट विज्ञापन प्रदर्शित होंगे। –

+0

क्या आपके पास कोई कोड या छद्म कोड है? पोस्ट करने से वह उत्तर प्राप्त करने में सहायता मिल सकती है जिसे आप प्राप्त करने का प्रयास कर रहे हैं। मैं इसे बलपूर्वक बल करने के कुछ तरीकों के बारे में सोच सकता हूं, लेकिन इसे एक पुनरावर्ती विधि (अभी तक) में दोबारा करने में सक्षम नहीं हूं। – Tim

उत्तर

0

मैं वास्तव में सोचा कि यह एक महान पुनरावर्ती क्रिया हो सकता है, लेकिन मैं यह लिख रहा है कि जिस तरह से नहीं समाप्त हो गया। आखिरकार, यह कोड मैंने बनाया है:

public IEnumerable<string> GetPermutations(IEnumerable<string> possibleCombos, string delimiter) 
{ 
    var permutations = new Dictionary<int, List<string>>(); 
    var comboArray = possibleCombos.ToArray(); 
    var splitCharArr = new char[] { ',' }; 

    permutations[0] = new List<string>(); 

    permutations[0].AddRange(
     possibleCombos 
     .First() 
     .Split(splitCharArr) 
     .Where(x => !string.IsNullOrEmpty(x.Trim())) 
     .Select(x => x.Trim())); 

    for (int i = 1; i < comboArray.Length; i++) 
    { 
     permutations[i] = new List<string>(); 
     foreach (var permutation in permutations[i - 1]) 
     { 
      permutations[i].AddRange(
       comboArray[i].Split(splitCharArr) 
       .Where(x => !string.IsNullOrEmpty(x.Trim())) 
       .Select(x => string.Format("{0}{1}{2}", permutation, delimiter, x.Trim())) 
       ); 
     } 
    } 

    return permutations[permutations.Keys.Max()]; 
} 

...

a/b/e/f/g/i 
a/b/e/f/h/i 
a/c/e/f/g/i 
a/c/e/f/h/i 
a/d/e/f/g/i 
a/d/e/f/h/i 

हर किसी के सुझाव के लिए धन्यवाद, वे वास्तव में बाहर छँटाई में मददगार थे क्या में किया जा करने के लिए आवश्यक:

IEnumerable<string> row = new string[] { "a", "b,c,d", "e", "f", "g,h", "i" }; 
IEnumerable<string> permutations = GetPermutations(row, delimiter: "/"); 
foreach(var permutation in permutations) 
{ 
    Debug.Print(permutation); 
} 

यह निम्न उत्पादन का उत्पादन: मेरे परीक्षण की स्थिति मुझे बिल्कुल उत्पादन मैं उम्मीद के साथ प्रदान की मेरा मन। मैंने आपके सभी उत्तरों को उखाड़ फेंक दिया है।

1

मुझे यकीन नहीं है कि यह सबसे सुंदर दृष्टिकोण है, लेकिन यह आपको शुरू हो सकता है।

private static IEnumerable<string> GetPermutations(IEnumerable<string> row, 
                string delimiter = "|") 
{ 
    var separator = new[] { ',' }; 
    var permutations = new List<string>(); 
    foreach (var cell in row) 
    { 
     var parts = cell.Split(separator); 
     var perms = permutations.ToArray(); 
     permutations.Clear(); 
     foreach (var part in parts) 
     { 
      if (perms.Length == 0) 
      { 
       permutations.Add(part); 
       continue; 
      } 
      foreach (var perm in perms) 
      { 
       permutations.Add(string.Concat(perm, delimiter, part)); 
      } 
     } 
    } 
    return permutations; 
} 

बेशक, अगर क्रमपरिवर्तन की क्रम महत्वपूर्ण है, तो आप एक .OrderBy() अंत में जोड़ सकते हैं।

संपादित करें: एक Alernative

तुम भी स्ट्रिंग सरणियों की एक सूची बना सकते हैं जोड़ा, क्रमपरिवर्तन का निर्धारण करने से पहले कुछ संख्या की गणना के द्वारा।

private static IEnumerable<string> GetPermutations(IEnumerable<string> row, 
                string delimiter = "|") 
{ 
    var permutationGroups = row.Select(o => o.Split(new[] { ',' })).ToArray(); 
    var numberOfGroups = permutationGroups.Length; 
    var numberOfPermutations = 
      permutationGroups.Aggregate(1, (current, pg) => current * pg.Length); 
    var permutations = new List<string[]>(numberOfPermutations); 

    for (var n = 0; n < numberOfPermutations; n++) 
    { 
     permutations.Add(new string[numberOfGroups]); 
    } 

    for (var position = 0; position < numberOfGroups; position++) 
    { 
     var permutationGroup = permutationGroups[position]; 
     var numberOfCharacters = permutationGroup.Length; 
     var numberOfIterations = numberOfPermutations/numberOfCharacters; 
     for (var c = 0; c < numberOfCharacters; c++) 
     { 
      var character = permutationGroup[c]; 
      for (var i = 0; i < numberOfIterations; i++) 
      { 
       var index = c + (i * numberOfCharacters); 
       permutations[index][position] = character; 
      } 
     } 
    } 

    return permutations.Select(p => string.Join(delimiter, p)); 
} 
1

आपने मुझे "रिकर्सिव" पर रखा था। यहाँ एक और सुझाव है:

private IEnumerable<string> GetPermutations(string[] row, string delimiter, 
              int colIndex = 0, string[] currentPerm = null) 
{ 
    //First-time initialization: 
    if (currentPerm == null) { currentPerm = new string[row.Length]; } 

    var values = row[colIndex].Split(','); 
    foreach (var val in values) 
    { 
     //Update the current permutation with this column's next possible value.. 
     currentPerm[colIndex] = val; 

     //..and find values for the remaining columns.. 
     if (colIndex < (row.Length - 1)) 
     { 
      foreach (var perm in GetPermutations(row, delimiter, colIndex + 1, currentPerm)) 
      { 
       yield return perm; 
      } 
     } 
     //..unless we've reached the last column, in which case we create a complete string: 
     else 
     { 
      yield return string.Join(delimiter, currentPerm); 
     } 
    } 
} 
1

एक एल्गोरिथ्म आप उपयोग कर सकते हैं मूल रूप से गिनती की तरह है:

  • प्रारंभ 0 आइटम के साथ प्रत्येक सूची में (00000)
  • वृद्धि अंतिम मान (00001, 00002 आदि ।)
  • जब आप एक मान को बढ़ा नहीं सकते हैं, इसे रीसेट करें और अगले (00009, 00010, 00011 इत्यादि)
  • जब आप कोई मूल्य नहीं बढ़ा सकते हैं, तो आप कर चुके हैं।

फंक्शन:

static IEnumerable<string> Permutations(
    string input, 
    char separator1, char separator2, 
    string delimiter) 
{ 
    var enumerators = input.Split(separator1) 
     .Select(s => s.Split(separator2).GetEnumerator()).ToArray(); 
    if (!enumerators.All(e => e.MoveNext())) yield break; 

    while (true) 
    { 
     yield return String.Join(delimiter, enumerators.Select(e => e.Current)); 
     if (enumerators.Reverse().All(e => { 
       bool finished = !e.MoveNext(); 
       if (finished) 
       { 
        e.Reset(); 
        e.MoveNext(); 
       } 
       return finished; 
      })) 
      yield break; 
    } 
} 

उपयोग:

foreach (var perm in Permutations("a|b,c,d|e|f|g,h|i", '|', ',', "/")) 
{ 
    Console.WriteLine(perm); 
}