2017-03-01 3 views
-2

Ich möchte alle Kombinationen einer Zeichenfolge finden, die Reihenfolge erhalten. Gibt es eine eingebaute Methode in Ruby, um dies zu erreichen?Ruby String/Array-Kombinationen Erhalt der Reihenfolge

Zum Beispiel "abcd".all_combinations sollte die Ausgabe geben:

a 
b 
c 
d 
ab 
bc 
cd 
abc 
bcd 
abcd 
+0

Muss es eine eingebaute Methode sein? –

+0

Jede Art von Implementierung würde funktionieren. Aber ich hoffe, dass es eine ähnliche Methode wie object.cobination geben würde – maddy

+0

Werfen Sie einen Blick auf http://apidock.com/ruby/Array/combination –

Antwort

3

Wahrscheinlich nicht die ideale Umsetzung, aber dies funktioniert:

def combinations(str) 
    items = str.chars 
    (1..items.length).map { |i| items.each_cons(i).map(&:join) }.flatten 
end 

Auch Enumerable#each_cons überprüfen. Sie können auch hinzufügen, es nur auf die String-Klasse wie folgt aus:

class String 
    def combinations 
    items = self.chars 
    (1..items.length).map { |i| items.each_cons(i).map(&:join) }.flatten 
    end 
end 

'abcd'.combinations 

Was geschieht:

  • wir den String machen eine tatsächliche Array von Zeichen mit String#chars.
  • dann für jede Zahl zwischen 1 i der Länge der Saite:
    • Anruf Enumerable#each_cons, die im Grunde die möglichen Kombinationen der Länge zu i als ein Array von Zeichen zurückgibt. Also, wenn i 2 ist, dann ist das Ergebnis von items.each_cons(2) wird [ ['a', 'b'], ['b', 'c'], ['c', 'd'] ]
    • werden, um die .map(&:join) Teil im Grunde Array#join an jedem der Elemente des Arrays von Arrays nennen, so wird es ['ab', 'bc', 'cd']
  • Das Ergebnis (1..items.length).map { |i| items.each_cons(i).map(&:join) } wird : [ ['a', 'b', 'c', 'd'], ['ab', 'bc', 'cd'], ['abc', 'bcd'], ['abcd'] ] Das ist ein Array von Arrays. Wir rufen Array#flatten darauf an, um es zu einem einfachen Array zu machen (lesen Sie den flatten Link für mehr).
+0

Das hat funktioniert, Vielen Dank! Ich bin neu in Ruby ... Kannst du uns bitte die Implementierung erklären? – maddy

+0

@maddy aktualisiert, hoffe das hilft. Sie müssen die Beschreibungen der verknüpften Methoden lesen, um eine bessere Vorstellung davon zu bekommen, was passiert. –

+0

@TamerSlash: Anstelle von 'Enumberable # each_cons' kann man' Array # combination' auch verwenden –

1

Es gibt keine eingebaute Funktion, die genau das tut, wonach Sie suchen.

String # each_cons sieht interessant aus, wie Tamer darauf hinweist.

Hier ist eine alternative Lösung:

def all_combos(str) 
    1.upto(str.length) do |segment_length| 
    0.upto(str.length - segment_length) do |starting_point| 
     puts str[starting_point, segment_length] 
    end 
    end 
end 

all_combos("abcd") 
+1

Sehr saubere Lösung. Obwohl ich jeden Teilstring "ausgeben" würde, anstatt ihn zu drucken, kann man ihn über 'all_combos ('abcd') {| s | setzt s} '. – Stefan

1

Die Start- und Endeindizes der Unterketten bilden ein Muster eine Kombination mit Wiederholung, für den Rubin hat eine integrierte Methode.

class String 
    def all_combinations 
    idx = (0 ... self.size).to_a 
    idx.repeated_combination(2){|i,j| yield self[i..j]} 
    end 
end 

"abcd".all_combinations{|combo| puts combo} 
+0

'each_combination' könnte ein besserer Name sein. – Stefan

Verwandte Themen