2016-04-01 4 views
-3

Geben Sie ein Array von Zeichen zurück, auf dem wir eine Eingabezeichenfolge teilen können, um Teilzeichenfolgen derselben Länge zu erzeugen.Auch Splitters.rb

Zählen Sie keine leeren Zeichenfolgen nach der Teilung.

Hier ist ein Beispiel für "Banane":

def even_splitters(str) 
    count = Hash.new(0) 
    new_arr = [] 
    str.chars.map do |e| 
    arr = str.split(e) 
    if arr == [] || arr.length == 1 
     new_arr << e 
    else 
     arr.each {|x| count[x] = x.length } 
     if count.values.uniq.length == 1 
     new_arr << e 
     end 
    end 
    end 
    p new_arr 
end 

puts "-----Even Splitters----" 
puts even_splitters("") == [] 
puts even_splitters("t") == ["t"] 
puts even_splitters("jk") == ["j", "k"] 
puts even_splitters("xoxo") == ["x", "o"] 
puts even_splitters("banana") == ["b","a"] 
puts even_splitters("mishmash") == ["m","h"] 
+0

hi, bitte beschreiben Sie, wie Ihr Code versagt und die Frage wird einfacher zu nähern. –

+0

hi, die Art, wie ich dachte, habe nicht realisiert, Count wird 0, wenn es eine leere Zeichenfolge ist. –

+0

Ja, ich sehe, wie das war überraschend.Wenn Ihre Frage gelöst ist, können Sie Ihre eigene Antwort posten oder die Frage schließen. Ich bin mir nicht sicher, ob diese Frage allgemein genug ist, um anderen zu helfen. –

Antwort

2

hier einige Vorschläge, wo Sie falsch gehen ...

def even_splitters(str) 
    new_arr = [] 
    # use #uniq here... you don't need to test every 'a' in 'banana' 
    str.chars.uniq.each do |e| 
    # initialize the hash **inside** the loop, otherwise count is just accumulating as each letter is tested 
    count = Hash.new(0) 
    # exclude empty strings 
    arr = str.split(e).reject(&:empty?) 
    arr.each {|x| count[x] = x.length } 
     # handle single character strings like "t"which have no values by saving if count.values.empty? 
     if count.values.uniq.length <= 1 
     new_arr << e 
     end 
    end 
    p new_arr 
end 

puts even_splitters("") == [] 
puts even_splitters("t") == ["t"] 
puts even_splitters("jk") == ["j", "k"] 
puts even_splitters("xoxo") == ["x", "o"] 
puts even_splitters("banana") == ["b","a"] 
puts even_splitters("mishmash") == ["m","h"] 
:

"banana".split("a") # => ["b", "n", "n"] (all elements same length) 
"banana".split("b") # => ["", anana"] 
(all elements same length - there's only 
one element "anana" because the empty string doesn't count) 
"banana".split("n") # => ["ba", "a", "a"] (all elements NOT same length) 

result: ["b", "a"] 

Hier ist mein Code

Hier ist eine kompaktere Lösung ...

def even_splitters(str) 
    str.chars.uniq.map do |e| 
    str.split(e).reject(&:empty?).map(&:length).uniq.count <= 1 ? e : nil 
    end.compact 
end 
+0

Hallo Steve, danke für deine Lösung, die mein Sprachloch füllt, um den Code zu realisieren, aber macht es dir etwas aus, mehr Gedanken oder Ressourcen darüber zu machen, Hash zwischen In-Schleife und außerhalb der Schleife zu machen? # initialisiere den Hash ** innerhalb ** der Schleife, ansonsten zählt sich nur, wenn jeder Buchstabe getestet wird –

+0

Und in deiner kompakten Lösung, warum benutzt du #compact, da du #uniq in deiner Schleife benutzt hast? –

+0

Oh, ich sehe, wenn Sie Schleife "n", gibt es "nil" zurück. Also musst du das tun. –

2

Edit: nachdem ich ein paar Änderungen an meinem Code vorgenommen habe, sehe ich, dass es jetzt sehr nah an @ Steves "kompakter Lösung" ist. Ich werde meine Antwort für den Abschnitt "Erläuterung" hinterlassen.

@SteveTurczyn hat Ihre Frage beantwortet und schlug auch eine alternative Methode vor. Hier ist ein anderer.

-Code

def even_splitters(str) 
    str.chars. 
     uniq. 
     select do |c| (str.split(c)-[""]). 
        map(&:size). 
        uniq. 
        size == 1 
     end 
end 

Beispiele

Beispiele Steves Verwendung,

even_splitters("") 
    #=> [] 
even_splitters("t") 
    #=> [] 
even_splitters("jk") 
    #=> ["j", "k"] 
even_splitters("xoxo") 
    #=> ["x", "o"] 
even_splitters("banana") 
    #=> ["b","a"] 
even_splitters("mishmash") 
    #== ["m","h"] 

Erklärung

Angenommen

str = "xoxo" 

Die Schritte sind wie folgt:

a = str.chars 
    #=> ["x", "o", "x", "o"] 
b = a.uniq 
    #=> ["x", "o"] 
b.select do |c| (str.split(c)-[""]). 
       map(&:size). 
       uniq. 
       size == 1 
end 
    #=> ["x", "o"] 

ist genauer an b.select aussehen lassen. Das erste Element des b wird an den Block übergeben und an die Blockvariable zugewiesen:

c = "x" 

und der Block Berechnung durchgeführt:

d = str.split(c) 
    #=> str.split("x") 
    #=> ["", "o", "o"] 
e = d - [""] 
    #=> ["o", "o"] 
f = e.map(&:size) 
    #=> [1, 1] 
g = f.uniq 
    #=> [1] 
g.size == 1 
    #=> true 

Da g.size==1 #=> true, "x" ausgewählt ist.

Als nächstes wird die zweite und letzte Element der b wird an den Block übergeben, und die Berechnungen werden durchgeführt:

c = "o" 
d = str.split(c) 
    #=> str.split("o") 
    #=> ["x", "x"] 
e = d - [""] 
    #=> ["x", "x"] 
f = e.map(&:size) 
    #=> [1, 1] 
g = f.uniq 
    #=> [1] 
g.size == 1 
    #=> true 

so "o" ist ebenfalls enthalten.

+1

Danke, Cary. Ich mag es, wie Sie #minmax_by verwenden, um das Ziel einzuschränken und auch #select anstelle von 'if' zu verwenden. Es ist sehr sauber und elegant. –

+0

Ja, 'Select' war ein guter Zug! – SteveTurczyn