2010-12-04 31 views
60

Tengo una matriz A. Me gustaría comprobar si contiene valores duplicados. ¿Cómo lo haría?¿Cómo verifico un conjunto de duplicados?

+14

"marcados como duplicados" Bueno, esto es bastante meta considerando la cuestión. – cpursley

+1

"¿Cómo verifico una matriz de duplicados?" no es exactamente la misma pregunta que "¿Cómo encontrar y devolver un valor duplicado en una matriz?". Esta pregunta se pregunta cómo determinar la singularidad de la matriz, mientras que la otra pregunta cómo extraer valores duplicados de la matriz. No creo que deba marcarse como duplicado, pero la otra pregunta es similar y debe estar vinculada en un comentario. – emery

+0

Pero la ironía es rica, ¿no? – oMiKeY

Respuesta

114

Sólo tiene que llamar uniq en él (que devuelve una nueva matriz sin duplicados) y ver si la matriz uniq ed tiene menos elementos que el original:

if a.uniq.length == a.length 
    puts "a does not contain duplicates" 
else 
    puts "a does contain duplicates" 
end 

Tenga en cuenta que los objetos de la matriz tienen que responder a hash y eql? en un significado para uniq para que funcione correctamente.

+8

Además, 'uniq!' Devolverá 'nil' si no se encuentran duplicados, alterando self para eliminar duplicados. Hay muchos métodos de matriz disponibles: http://ruby-doc.org/core/classes/Array.html – David

+2

Por supuesto, si no responden a 'eql?' De una manera significativa, entonces ¿qué hace? duplicar "incluso ** significa **? Y una vez que haya definido 'eql?', 'Hash' debe ser consistente con él. –

+1

@Karl: ¿Que dos elementos en la matriz son '==' el uno al otro? – sepp2k

32

el fin de encontrar los elementos duplicados, utilizo este método (con Ruby 1.9.3):

array = [1, 2, 1, 3, 5, 4, 5, 5] 
=> [1, 2, 1, 3, 5, 4, 5, 5] 
dup = array.select{|element| array.count(element) > 1 } 
=> [1, 1, 5, 5, 5] 
dup.uniq 
=> [1, 5] 
+3

select {array.count} es un bucle anidado, está haciendo un algoritmo complejo O (n^2) para algo que se puede hacer en O (n). – apeiros

+1

Tiene razón, para resolver la pregunta de este Skizit que podemos usar en O (n); pero para descubrir qué elementos están duplicados, un O (n^2) algo es la única forma en que puedo pensar hasta ahora. – jmonteiro

+3

ordena y elimina consecutivos para n log n – user3125280

4

posible que desee monkeypatch matriz si se utiliza más de una vez:

class Array 
    def uniq? 
    self.length == self.uniq.length 
    end 
end 

entonces:

irb(main):018:0> [1,2].uniq? 
=> true 
irb(main):019:0> [2,2].uniq? 
=> false 
+14

Evitaría parches de monos para envolver un trazador de líneas. –

+0

parches de mono tienden a morder –

+0

@sidewaysmilk ¿por qué se debe evitar esto? Parece el camino ruby: elegante, dinámico y seco. – hamstar

9

Si usted quiere volver los duplicados, se puede hacer esto:

dups = [1,1,1,2,2,3].group_by{|e| e}.keep_if{|_, e| e.length > 1} 
# => {1=>[1, 1, 1], 2=>[2, 2]} 

Si sólo desea los valores:

dups.keys 
# => [1, 2] 

Si desea que el número de duplicados:

dups.map{|k, v| {k => v.length}} 
# => [{1=>3}, {2=>2}] 
Cuestiones relacionadas