2010-05-18 3 views
8

Dans ruby, comment tester qu'un tableau a non seulement les éléments d'un autre tableau, mais les contient dans cet ordre particulier?Déterminer si un tableau contient le contenu d'un autre tableau dans ruby ​​

correct_combination = [1, 2, 3, 4, 5] 
[1, 5, 8, 2, 3, 4, 5].function_name(correct_combination) # => false 
[8, 10, 1, 2, 3, 4, 5, 9].function_name(correct_combination) # => true 

J'ai essayé d'utiliser include, mais qui est utilisé pour vérifier si [1,2,3].include?(2) est vrai ou non.

+0

question similaire à http://stackoverflow.com/questions/6993848/comparing-sequences-in-ruby –

+0

@jassa J'ai essayé d'utiliser (sans 'should', qui est une chose rspec), et les deux '[8, 10, 1, 2, 3, 4, 5, 9] = ~ right_combination' et' correct_combination = ~ [8, 10, 1, 2, 3, 4, 5, 9 ] 'retourné' nil' pour ruby ​​2.0.0dev (2011-11-27 tronc 33860). –

+0

Vous avez raison, laissez-moi élaborer – jassa

Répondre

14

Vous pouvez utiliser each_cons méthode:

arr = [1, 2, 3, 4, 5] 
[1, 5, 8, 2, 3, 4, 5].each_cons(arr.size).include? arr 

Dans ce cas, il fonctionnera pour tous les éléments.

+0

Je pense que each_cons est seulement disponible en Ruby 1.9? Mais une bonne solution. –

+3

Il est également en 1.8.7. –

3

Pas exactement la meilleure solution possible, mais au moins il est bref

(',' + [1, 5, 8, 2, 3, 4, 5].join(',') + ',').include?(',' + correct_combination.join(',') + ',') 

La meilleure solution possible serait d'employer l'un des string searching algorithms sur la matrice, mais vous auriez à ce code vous-même, je ne pense pas il y a une solution standard.

-3

Vous pouvez simplement comparer les tableaux sous forme de chaînes:

correct_combination = [1, 2, 3, 4, 5] 
yep = [8, 10, 1, 2, 3, 4, 5, 9] 
nope = [1, 5, 8, 2, 3, 4, 5] 
if yep.to_s.include?(correct_combination.to_s) 
    puts "yep" 
end 
if nope.to_s.include?(correct_combination.to_s) 
    puts "nope" 
end 
+1

http://stackoverflow.com/questions/1553462/check-if-a-string-contains-a-certain-number/1553489#1553489 est encore une fois :) – vava

+0

'yep. to_s.include? (correct_combination.to_s) 'renvoie false, en raison du crochet fermant' correct_combination'. –

-2

Peut-être que <=> est ce que vous cherchez.

Comparaison-retour un nombre entier (-1, 0 ou +1) si cette matrice est inférieure, égale ou supérieure à other_array

a = [1, 2, 3, 4, 5] 
b = [1, 5, 8, 2, 3, 4, 5] 
c = [8, 10, 1, 2, 3, 4, 5, 9] 

puts a <=> b # => -1 
puts a <=> C# => -1 
puts a <=> a # => 0 

Update: trop grave, vient de noter qu'il ne se soucie pas de la position.

puts a <=> a.reverse # => -1 
-2

C'est le meilleur que je pourrais trouver. Tous les appels return sont un peu moche, mais il devrait être plus rapide que de faire une comparaison de chaîne si c'est de grands tableaux.

class Array 
    def same?(o) 
    if self.size == o.size 
     (0..self.size).each {|i| return false if self[i] != o[i] } 
    else 
     return false 
    end 

    return true 
    end 
end 

a = [1,2,3,4,5] 
b = [1, 5, 8, 2, 3, 4, 5] 
c = [1, 2, 6, 4, 5] 

puts a.same?(a.reverse) # => false 
puts a.same?(a) # => true 
puts a.same?(b) # => false 
puts a.same?(c) # => false 
+0

Je vois maintenant que j'ai mal compris la question complètement. Yossi Zach semble être sur la bonne réponse avec 'each_cons'. :) – gaqzi

+0

vous n'avez pas besoin d'écrire explicitement 'return true' dans Ruby vous pouvez simplement écrire' true' – Agush

4

Si vous voulez ignorer l'ordre, (comme je l'ai fait quand je suis tombé sur ce poste), vous pouvez utiliser Array.sort et < => http://ruby-doc.org/core-1.8.7/classes/Array.html#M000316

a = [1, 2, 3, 4, 5] 
b = [2, 1, 5, 4, 3] 
a.sort <=> b.sort 

Vous devez ensuite vérifiez que la valeur de sortie est 0.

+0

Cela fonctionnerait-il si un tableau avait plus de contenu que l'autre? –

+0

Non, car <=> teste l'égalité, et nous avons fait en sorte que si les mêmes valeurs sont dans chaque tableau, elles seront égales une fois toutes les deux triées. Comme la documentation liée dit: Ainsi, deux tableaux sont '' égaux '' selon le tableau # <=> si et seulement s'ils ont la même longueur et la valeur de chaque élément est égale à la valeur de l'élément correspondant dans l'autre tableau. –

-2

Un moyen très rapide de le faire consiste simplement à soustraire un tableau de l'autre et à tester un tableau vide.

correct_combination = [1, 2, 3, 4, 5] 
yep = [8, 10, 1, 2, 3, 4, 5, 9] 
nope = [1, 8, 2, 3, 4] 
if correct_combination - yep == [] 
    puts "yep has all the values" 
end 
if correct_combination - nope == [] 
    puts "nope has all the values" 
end 

Cette approche ne se soucie pas de la position, donc supprimez-la!

Désolé ... J'ai aussi manqué le point à la question. Je n'ai pas réalisé que vous cherchiez l'ordre de préséance. Je suis tombé sur ceci en cherchant une solution pour évaluer si un grand tableau contenait toutes les entrées d'un autre grand tableau. Le .all?/Include? approche prend beaucoup de temps à compléter. Bonne chance!

10

Je pense que cela peut être fait simplement.

class Array 
    def contain? other; (self & other) == other end 
end 

correct_combination = [1, 2, 3, 4, 5] 
[1, 5, 8, 2, 3, 4, 5].contain?(correct_combination) # => false 
[8, 10, 1, 2, 3, 4, 5, 9].contain?(correct_combination) # => true 
+2

Je ne pense pas que ce soit exact pour vérifier que les numéros apparaissent dans l'ordre donné. Par exemple, si 'right_combination = [1,3,4]' then [[1, 5, 8, 2, 3, 4, 5] .contain? (Correct_combinaison) 'renvoie vrai. – davemyron

+0

C'est le résultat attendu. Vous n'avez peut-être pas compris la question. – sawa

-1

Je voudrais suggestion une boucle qui compare chacun

@out_of_order_elements = [] 

for i in 0.. @array_size do 
    unless submission_array[i] == @correct_combination[i] 
    @out_of_order_ids.push(@submission_array[i]) 
    end 
end 
0

C'est ce que je suis venu avec

a = [1, 2, 3, 4, 5] 
b = [2, 3, 5] 
c = [3, 9] 

irb(main):037:0* (a + b).sort.uniq == a.sort.uniq 
=> true 
irb(main):038:0> (a + c).sort.uniq == a.sort.uniq 
=> false 
0

Je voudrais considérer la séquence continue d'éléments d'autre tableau dans le tableau conteneur et présente ceci: - le code est inspiré du code de Sawa

class Array 
    def contain? other 
    arr = self & other 
    (arr.eql? other) && ((self.index(arr.last) - self.index(arr.first)).eql?(other.size - 1)) 
    end 
end 

Résultat: -

correct_combination = [1, 2, 3, 4, 5] 
[1, 5, 8, 2, 3, 4, 5].contain?(correct_combination) # => false 
[8, 10, 1, 2, 3, 4, 5, 9].contain?(correct_combination) # => true 
[1, 8, 2, 3, 4, 5].contain?(correct_combination) # => false 
+0

@orangechicken Cherchez-vous cela? –

+0

Ce code est difficile à comprendre pour moi. –

+0

logique @AndrewGrimm est 1. intersection de conteneur et tableau de combinaison doit être égale à la combinaison, 2. soustraction de l'indice du premier élément de combinaison dans le conteneur de l'indice du dernier élément de combinaison dans le conteneur doit être égale à la taille de la combinaison moins un. Voir des exemples dans la réponse. –

Questions connexes