2010-04-29 17 views
5

Mi problema es el siguiente. Tengo un arraylist de enteros. El arraylist contiene 5 entradas por ej. [5,5,3,3,9] o quizás [2,2,2,2,7]. Muchas de las listas de arreglos tienen valores duplicados y no estoy seguro de cómo contar cuántos de cada uno de los valores existen.¿Cómo encontrar múltiplos del mismo número entero en una lista de arrays?

El problema es cómo encontrar los valores duplicados en el arraylist y contar cuántos de esos duplicados particulares hay. En el primer ejemplo [5,5,3,3,9] hay 2 5's y 2 3's. El segundo ejemplo de [2,2,2,2,7] sería solo 4 2's. La información resultante que deseo encontrar es si hay duplicados cuántos de ellos hay y qué número entero específico se ha duplicado.

No estoy muy seguro de cómo hacer esto en Java.

Cualquier ayuda sería muy apreciada. Gracias.

Respuesta

6

Para mí, la respuesta más sencilla, sería utilizando el método Collections.frequency.Algo a lo largo de las líneas de esto:

// Example ArrayList with Integer values 
ArrayList<Integer> intList = new ArrayList<Integer>(); 
intList.add(2); 
intList.add(2); 
intList.add(2); 
intList.add(2); 
intList.add(7); 

Set<Integer> noDupes = new HashSet<Integer>(); 
noDupes.addAll(intList); // Remove duplicates 

for (Integer i : noDupes) { 
    int occurrences = Collections.frequency(intList, i); 
    System.out.println(i + " occurs " + occurrences + " times."); 
} 

Si desea, puede asignar cada Integer con su número de apariciones:

Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 
for (Integer i : noDupes) { 
    map.put(i, Collections.frequency(intList, i)); 
} 
+0

su primera respuesta también es ideal, ¡lo intenté funciona muy bien! ¡Gracias! – Julio

+1

Esto parece ser 'O (N^2)', cuando 'O (N log N)' es el límite superior con ordenamiento basado en la comparación. 'O (N)' posible si la ordenación no basada en comparación es aplicable. – polygenelubricants

5

Dos algoritmos me vienen a la mente.

Ordenar (Collections.sort). Luego itera para encontrar fácilmente a los incautos.

Iterar a través del conteo en un Map<Integer,Integer> (o Map<Integer,AtomicInteger> para un conteo mutable). Un poco feo de esta manera.

De cualquier manera, la codificación debe ser un ejercicio instructivo. Sugiero hacer las dos cosas y comparar.

+2

Variación en # 2: repetir una vez para llenar el mapa con (en el ejemplo) [5, 0], [3, 0], [9, 0]; luego, una segunda vez para obtener los conteos. Encuentro esta lógica más simple que verificar, en cada punto, si el valor ya es una clave del mapa. –

+0

@Carl Me gusta eso. –

+0

Ese comentario parece más o menos. Nunca he usado mapas antes, así que no estoy seguro de cómo hacerlo – Julio

1

utilizar una colección Hashmap además de la lista de arreglo donde

  • la tecla Hashmap es el valor int matriz única y
  • el valor Hashmap a la clave es el recuento de cada valor encontrado.

Acceda a la lista de arreglos recopilando estos valores en el hashmap agregando un nuevo elemento cuando no exista una tecla anterior e incremente en 1 los valores de las claves que ya existen. A continuación, itere sobre Hashmap e imprima cualquier clave donde el valor sea> 1.

1

Puede ir a través del List y ponerlos en un Map con el recuento. Entonces es fácil descubrir cuál es duplicado.

+0

Nunca Mapas usados ​​antes en Java, ¿alguna idea de cómo voy a hacer esto? ¡Salud! – Julio

0

Para una abstracción más clara de lo que está haciendo, puede utilizar la estructura de datos Multiset de guava/google-collections. Incluso puede encontrar que prefiere usarlo que List, dependiendo de lo que esté haciendo con él (si no necesita el orden determinista de una lista). Se podría utilizar de esta manera:

Multiset<Integer> multiset = HashMultiset.create(list); 
int count = multiset.count(3); // gets the number of 3s that were in the list 

En términos de lo que lo anterior está haciendo bajo las sábanas, es casi exactamente equivalente a la sugerencia de construir un Map<Integer,AtomicInteger> basado en su lista.

3

Aquí es una aplicación concreta, con la prueba, de lo que he descrito en los comentarios a la respuesta de Tom @:

package playground.tests; 

import java.util.HashMap; 
import java.util.HashSet; 
import java.util.Map; 
import java.util.concurrent.atomic.AtomicInteger; 

import junit.framework.TestCase; 

public class DupeCounterTest extends TestCase { 

    public void testCountDupes() throws Exception { 
     int[] array = new int[] { 5, 5, 3, 3, 9 }; 
     assertEquals("{3=2, 5=2}", countDupes(array).toString()); 
    } 

    private Map<Integer, AtomicInteger> countDupes(int[] array) { 
     Map<Integer, AtomicInteger> map = new HashMap<Integer, AtomicInteger>(); 
     // first create an entry in the map for every value in the array 
     for (int i : array) 
      map.put(i, new AtomicInteger()); 
     // now count all occurrences 
     for (int i : array) 
      map.get(i).addAndGet(1); 
     // now get rid of those where no duplicate exists 
     HashSet<Integer> discards = new HashSet<Integer>(); 
     for (Integer i : map.keySet()) 
      if (map.get(i).get() == 1) 
       discards.add(i); 
     for (Integer i : discards) 
      map.remove(i); 
     return map; 
    } 

} 
+0

¡genial! :-) ¡Un poco de retoque ayuda mucho! – Julio

Cuestiones relacionadas