Ottenere tutte le combinazioni in un array

Dì che ho il seguente array:

var arr = new[] { "A", "B", "C" }; 

Come posso produrre tutte le combinazioni possibili che contengono solo due caratteri e non due uguali (ad esempio AB sarebbe uguale a BA ). Ad esempio, usando l’array sopra riportato produrrebbe:

 AB AC BC 

Si prega di notare che questo esempio è stato semplificato. La matrice e la lunghezza della stringa richiesta saranno maggiori.

Sarei davvero grato se qualcuno potesse aiutarti.

Lo estendiamo, quindi forse possiamo vedere lo schema:

 string[] arr = new string[] { "A", "B", "C", "D", "E" }; //arr[0] + arr[1] = AB //arr[0] + arr[2] = AC //arr[0] + arr[3] = AD //arr[0] + arr[4] = AE //arr[1] + arr[2] = BC //arr[1] + arr[3] = BD //arr[1] + arr[4] = BE //arr[2] + arr[3] = CD //arr[2] + arr[4] = CE //arr[3] + arr[4] = DE 

Vedo due anelli qui.

  • Il primo loop (esterno) va da 0 a 3 (arr.Length – 1)
  • Il secondo ciclo (interno) va dal contatore dei circuiti esterni + 1 a 4 (arr.Length)

Ora dovrebbe essere facile da tradurre in codice!

Poiché l’ordine non ha importanza, queste sono in realtà combinazioni e non permutazioni. In ogni caso, qui c’è un codice di esempio (si desidera la sezione “Combinazioni (cioè senza ripetizione)”.

Ciò che stai chiedendo sono combinazioni, non permutazioni (quest’ultimo termine implica che l’ordine contenga). Ad ogni modo, è un uso classico per la ricorsione. Nello pseudo-codice:

 def combs(thearray, arraylen, currentindex, comblen): # none if there aren't at least comblen items left, # or comblen has gone < = 0 if comblen > arraylen - currentindex or comblen < = 0: return # just 1 if there exactly comblen items left if comblen == arraylen - currentindex: yield thearray[currentindex:] return # else, all combs with the current item...: for acomb in combs(thearray, arraylen, currentindex+1, comblen-1): yield thearray[currentindex] + acomb # ...plus all combs without it: for acomb in combs(thearray, arraylen, currentindex+1, comblen): yield acomb 
 public string[] Permute(char[] characters) { List strings = new List(); for (int i = 0; i < characters.Length; i++) { for (int j = i + 1; j < characters.Length; j++) { strings.Add(new String(new char[] { characters[i], characters[j] })); } } return strings.ToArray(); } 

È la sum di 1 a n-1 o n (n-1) / 2.

 int num = n * ( n - 1 ) / 2; 

Ovviamente è ansible generalizzare il n * (n – 1) usando una coppia di fattoriali per qualsiasi cosa si stia tentando di fare (dimensione della stringa saggia).

Non testato e non il più veloce, ma:

 IEnumerable Combine(String text, IEnumerable strings) { return strings.Select(s => text + s).Concat(Combine(strins.Take(1).First(), strings.Skip(1)) } 

Chiamata:

 foreach (var s in Combine("" , arrayOfStrings)) { // print s } 

Ha scritto una risposta per una domanda che si è rivelata contrassegnata come duplicata, che indica qui.

 var arr = new[] { "A", "B", "C" }; var arr2 = arr1.SelectMany( x => arr1.Select( y => x + y)); 

Prodotto l’output corretto quando enumerato in console in VS2013. SelectMany appiattirà l’ IEnumerable interno generato dalla Select interna.

Quello che stai cercando è un doppio Loop lungo le linee del seguente pseudo-codice.

 for(int i = FirstElement; i< = LastElement; increment i) { for(j = i; j<= lastElement; increment j) { if(i != j) { print (i, j) } } }