2010-12-04 5 views
2

J'ai besoin d'une méthode écrite en Ruby, qui calcule les Variations. Je l'ai déjà écrit en Java, mais comme je suis nouveau à Ruby, il y a quelque chose qui me manque dans l'implémentation de Ruby.Variation Ruby avec répétition de la méthode Buggy

La méthode est suposed à faire:
méthode (1, "01") => [ "0", "1"]
méthode (2, "01") => [ "00", "01", "10", "11"] ... alors vous avez l'idée.

Note: dans le Ruby impl, je donne paralms comme ceci: méthode (2, [ "0", 1" ]), mais ce n'est pas un problème

Mon Java impl:.

public static List<String> Variations(int strength, String usableChars) { 
    List<String> list = 
     new ArrayList<String>((int) Math.pow(usableChars.length(), strength)); 

    if (strength == 0) { 
     list.add(""); 
    } else { 
     List<String> l = Variations(strength - 1, usableChars); 
     for (char c : usableChars.toCharArray()) { 
      for (String s : l) { 
       list.add(c + s); 
      } 
     } 
    } 
    return list; 
} 

Et cela fonctionne bien, mais c'est ma mise en œuvre Ruby.

def Variation (strength, arrayOfString) 
    array = Array.new(arrayOfString.size**strength) 

    if strength == 0 
     array << "" 
    else 
     a = Variation(strength-1, arrayOfString) 
     for i in arrayOfString do 
      for j in a do 
       array << (i + j) 
      end 
     end 
    end 
    return array 
end 

dans ce que je continue à recevoir un message d'erreur test.rb: 10: `Variation ': ne peut pas convertir nulle en chaîne (TypeError).

Répondre

2

En Ruby, les réseaux se développent automatiquement au besoin. Donc, changer votre initialisation de tableau à partir de:

array = Array.new(arrayOfString.size**strength) 

à

array = [] 

Pour énumérer sur chaque caractère dans une chaîne, au lieu de

for i in arrayOfString do 

faire:

arrayOfString.each_char do |i| 

Le résultat final:

#!/usr/bin/ruby1.8 

def Variation (strength, arrayOfString) 
    array = [] 
    if strength == 0 
    array << "" 
    else 
    a = Variation(strength - 1, arrayOfString) 
    arrayOfString.each_char do |i| 
     for j in a do 
     array << (i + j) 
     end 
    end 
    end 
    return array 
end 

p Variation(2, '01') # => ["00", "01", "10", "11"] 

each_char est en Ruby> = 1.8.7, ou vous pouvez l'obtenir à partir du backports gem.

+0

Merci, fonctionne très bien. J'ai déclaré la taille du tableau intentionnellement, afin de ne pas augmenter la taille chaque fois que j'ajoute un nouvel élément (en Java je n'ai pas besoin de déclarer la taille non plus). Y a-t-il un moyen de le faire dans Ruby? –

+0

Si je me souviens bien, Ruby réalloue la mémoire du tableau en morceaux, de sorte qu'elle n'a pas besoin d'être réaffectée à chaque fois qu'elle est développée. Mais pour allouer un tableau de 'size' nils,' [nil] * size' le fera. –

+0

@ user245543, je suis retourné à la source (array.c); ma mémoire est correcte. Ruby crée des tableaux avec assez d'espace pour 16 éléments et les développe ensuite en morceaux au besoin (si je ne me trompe pas, plus il y a d'éléments dans le tableau, plus il y a de mémoire). Le temps utilisé pour allouer des tableaux devrait rarement poser problème. –