2015-05-06 8 views
8

Die Anweisungen:Generieren Permutationen unter Verwendung polymorphen Methode

Schreiben ein Stück Code, das eine Liste als eine Eingabe in dem nimmt jedes Element eine andere Liste ist eine unbekannte Art enthalten und die gibt eine Liste aller mögliche Listen, die erhalten werden können, indem ein Element aus jeder der Eingangslisten genommen wird.

Zum Beispiel:

[[1, 2], [3, 4]] sollte zurückgeben: [[1, 3], [1, 4], [2, 3], [2, 4]].

[['1'], ['2'], ['3', '4']], sollte [['1', '2', '3'], ['1', '2', '4']].

Mein Code:

public static void Main(string[] args) 
{ 
    //Create a list of lists of objects. 
     var collections = new List<List<object>>(); 
     collections.Add(new List<object> { 1, 5, 3 }); 
     collections.Add(new List<object> { 7, 9 }); 
     collections.Add(new List<object> { "a", "b" }); 

    //Get all the possible permutations 
     var combinations = GetPermutations(collections); 

    //Loop through the results and display them in console 
     foreach (var result in combinations) 
     { 
      result.ForEach(item => Console.Write(item + " ")); 
      Console.WriteLine(); 
     } 

     Console.WriteLine("Press any key to exit."); 
     Console.ReadKey(); 
} 

private static List<List<object>> GetPermutations(List<List<object>> collections) 
{ 
     List<List<object>> permutations = new List<List<object>>(); 

     //Check if the input list has any data, else return the empty list. 
     if (collections.Count <= 0) 
      return permutations; 

     //Add the values of the first set to the empty List<List<object>> 
     //permutations list 
     foreach (var value in collections[0]) 
      permutations.Add(new List<object> { value }); 


     /* Skip the first set of List<List<object>> collections as it was 
     * already added to the permutations list, and loop through the 
     * remaining sets. For each set, call the AppendValues function 
     * to append each value in the set to the permuations list. 
     * */ 
     foreach (var set in collections.Skip(1)) 
      permutations = AppendNewValues(permutations, set); 

     return permutations; 
} 

private static List<List<object>> AppendNewValues(List<List<object>> permutations, List<object> set) 
{ 
     //Loop through the values in the set and append them to each of the 
     //list of permutations calculated so far. 
     var newCombinations = from additional in set 
           from value in permutations 
           select new List<object>(value) { additional }; 

     return newCombinations.ToList(); 
} 

Wie konnte ich es mit polymorphen Methode funktioniert, die eine generische Liste zurückgibt?

+1

Bedeutet "polymorphe Methode" "generische Methode" oder etwas anderes in Ihrem Beitrag? (Ich sehe nicht "Polymorphismus" in der Probe) ... –

+0

@AlexeiLevenkov - Ich denke, es bedeutet "generische Methode". Ich rate aber nur hier. – NomadTraveler

+0

"von jeder Art" schreit auf jeden Fall Generika, aber sie sind Terminologie, die sie verwendet wird, ist unscharf. – jdphenix

Antwort

3

schreiben Bitte ein Stück Code, das eine Liste als eine Eingabe in dem nimmt jedes Element eine andere Liste ist eine unbekannte Art enthält, und der eine Liste aller möglichen Listen zurückgibt, die der, indem ein Element aus jeder erhalten werden kann, die Eingabelisten.

Ich hätte um eine Klarstellung gebeten, etwas wie "Sie meinen dann eine generische Methode?"

Spricht man von Polymorphismus, sie waren in der Lage, wahrscheinlich nur eine Methode zu schreiben und nennt es, jede beliebige Art zu bilden, so etwas wie:

public static IList<IList<T>> GetPermutations<T>(IList<IList<T>> inputLists) { 
    if (inputLists.Count < 2) { 
     // special case. 
    } 

    return _permutationHelper(0, inputLists); 
} 

private static IList<IList<T>> _permutationHelper<T>(int i, IList<IList<T>> inputLists) { 
    IList<IList<T>> returnValue = new List<IList<T>>(); 
    if (i == inputLists.Count) { 
     returnValue.Add(new List<T>()); 
    } else { 
     foreach (var t in inputLists[i]) { 
      foreach (var list in _permutationHelper(i + 1, inputLists)) { 
       list.Add(t); 
       returnValue.Add(list); 
      } 
     } 
    } 

    return returnValue; 
} 

Es ist wahr, dass Ihre Implementierung beliebige Typen zur Laufzeit ermöglichen würde, , aber es verliert die Sicherheit. Angesichts der Tatsache, dass es sich um eine Implementierung in C# handelt, ist die Art der Sicherheit, die benötigt wird, eine sichere Schätzung - aber es tut auch nicht weh, danach zu fragen.

Eine andere Sache bemerkens - sie hätte sagen können, nur wurden sie für die Cartesian product der gegebenen Listen suchen.

+0

Danke @jdphenix. Du hast Recht - hätte zu Beginn mehr Informationen verlangen sollen. – NomadTraveler

1

Ich kann nur daran denken, dass sie nicht versucht haben, verschiedene Typen in den Listen zu mischen (wie Sie es implementiert haben), die Typen aller Listen wären gleich und sie wollten eine generische Klasse schreiben, die die Problem für verschiedene Arten von Listen, die sich in etwa wie folgt:

static void Main(string[] args) 
{ 
    var intCollections = new List<List<int>>(); 
    intCollections.Add(new List<int> { 1, 5, 3 }); 
    intCollections.Add(new List<int> { 7, 9 }); 

    var stringCollections = new List<List<String>>(); 
    stringCollections.Add(new List<String> { "a", "b" }); 
    stringCollections.Add(new List<String> { "c","d", "e" }); 
    stringCollections.Add(new List<String> { "g", "f" }); 

    //here you would have the "polymorphism", the same signature for different Lists types 

    var intCombinations = GetPermutations(intCollections); 
    var stringCombinations = GetPermutations(stringCollections); 

    foreach (var result in intCombinations) 
    { 
     result.ForEach(item => Console.Write(item + " ")); 
     Console.WriteLine(); 
    } 

    Console.WriteLine(); 

    foreach (var result in stringCombinations) 
    { 
     result.ForEach(item => Console.Write(item + " ")); 
     Console.WriteLine(); 
    } 

    Console.WriteLine("Press any key to exit."); 
    Console.ReadKey(); 
} 

//This would be your generic implementation, basically changing from object to T and adding <T> after method 

private static List<List<T>> GetPermutations<T>(List<List<T>> collections) 
{ 
    List<List<T>> permutations = new List<List<T>>(); 

    //Check if the input list has any data, else return the empty list. 
    if (collections.Count <= 0) 
     return permutations; 

    //Add the values of the first set to the empty List<List<object>> 
    //permutations list 
    foreach (var value in collections[0]) 
     permutations.Add(new List<T> { value }); 


    /* Skip the first set of List<List<object>> collections as it was 
     * already added to the permutations list, and loop through the 
     * remaining sets. For each set, call the AppendValues function 
     * to append each value in the set to the permuations list. 
     * */ 
    foreach (var set in collections.Skip(1)) 
     permutations = AppendNewValues(permutations, set); 

    return permutations; 
} 

private static List<List<T>> AppendNewValues<T>(List<List<T>> permutations, List<T> set) 
{ 
    //Loop through the values in the set and append them to each of the 
    //list of permutations calculated so far. 
    var newCombinations = from additional in set 
          from value in permutations 
          select new List<T>(value) { additional }; 

    return newCombinations.ToList(); 
} 

diese generische Implementierung, bei Ihnen zu vergleichen, den Vorteil des Typs Sicherheit haben, macht es sicher, dass Sie nicht verschiedene Objekttypen mischen.

+0

Prost @Rodrigo, bedeutet das aber nicht, dass meine Implementierung immer noch verschiedene Arten von Eingabedaten verarbeitet? – NomadTraveler

+1

Ihre Implementierung ist flexibler, da Ihre Listen unterschiedliche Typen haben können. Aber aus Ihrem Feedback und den Beispielen, die zur Verfügung gestellt wurden, scheint es, dass dieses Verhalten nicht erwünscht war (sie suchten nach Listen des gleichen Typs) und die generische Lösung bot diese Art von Sicherheit. –

Verwandte Themen