2010-11-16 18 views
8

Tengo una asignación para crear un algoritmo para buscar duplicados en una matriz que incluye valores numéricos. pero no ha dicho qué tipo de números, números enteros o flotantes. He escrito el siguiente pseudocódigo:Algoritmo para buscar duplicados en una matriz

FindingDuplicateAlgorithm(A) // A is the array 
     mergeSort(A); 
     for int i <- 0 to i<A.length 
      if A[i] == A[i+1] 
       i++ 
       return A[i] 
      else 
       i++ 

¿he creado un algoritmo eficiente? Creo que hay un problema en mi algoritmo, devuelve números duplicados varias veces. por ejemplo, si array incluye 2 en dos para dos índices tendré ... 2, 2, ... en la salida. ¿Cómo puedo cambiarlo para devolver cada duplicado solo una vez? Creo que es un buen algoritmo para enteros, pero ¿funciona también para números flotantes?

+2

Tenga cuidado al usar A [i + 1] - si i = (A.length - 1), sucederán cosas malas. Desea que el bucle for continúe solo cuando Seth

+0

es correcto, gracias por su guía –

Respuesta

10

Para manejar duplicados, puede hacer lo siguiente:

if A[i] == A[i+1]: 
    result.append(A[i]) # collect found duplicates in a list 
    while A[i] == A[i+1]: # skip the entire range of duplicates 
     i++    # until a new value is found 
+0

+1 Pero detectar puntos flotantes duplicados no es más complicado que detectar duplicados. Dos valores de coma flotante son idénticos si y solo si 'value1 == value2'. –

+0

@Andreas: Tiene razón, pero las palabras * igual * y * duplicado * significan algo diferente para los números de coma flotante. –

+2

No, no lo creo. Un valor 'a' es un duplicado de otro valor' b' si y solo si 'a == b', no hay otra manera de definirlo. –

1

No estoy seguro de en qué idioma necesita escribir el algoritmo, pero hay algunas soluciones de C++ realmente buenas en respuesta a my question aquí. Debería ser útil para usted.

+1

Quiero escribirlo en java –

0

Su algoritmo contiene un desbordamiento de búfer. i comienza con 0, por lo que supongo que los índices en la matriz A son de base cero, es decir, el primer elemento es A[0], el último es A[A.length-1]. Ahora i cuenta hasta A.length-1, y en el cuerpo del bucle accede a A[i+1], que está fuera de la matriz para la última iteración. O, simplemente, si está comparando cada elemento con el siguiente elemento, solo puede hacer comparaciones de longitud-1.

Si solo desea reportar duplicados una vez, usaría una variable bool firstDuplicate, que está configurada en falso cuando encuentra un duplicado y verdadero cuando el número es diferente al siguiente. Entonces solo reportarías el primer duplicado informando solamente los números duplicados si firstDuplicate es verdadero.

2

Tu respuesta parece bastante buena. Primero clasificándolos y simplemente revisando los valores vecinos, obtienes O(n log(n)) complejidad que es bastante eficiente.

Merge sort es O(n log(n)) mientras se comprueban los valores vecinos es simplemente O(n).

Sin embargo, una cosa (como se menciona en uno de los comentarios) es que obtendrá un desbordamiento de pila (lol) con su pseudocódigo. El bucle interno debe ser (en Java):

for (int i = 0; i < array.length - 1; i++) { 
    ... 
} 

Entonces también, si realmente desea mostrar qué números (o índices y) son los duplicados, tendrá que guardarlos en una lista separada.

5

¿Desea encontrar Duplicados en Java?

Puede usar un HashSet.

HashSet h = new HashSet(); 
for(Object a:A){ 
    boolean b = h.add(a); 
    boolean duplicate = !b; 
    if(duplicate) 
     // do something with a; 
} 

El retorno Valor de add() se define como:

cierto si el conjunto no lo hizo ya contienen el elemento especificado.

EDIT: Sé HashSet está optimizado para las inserciones y contiene operaciones.Pero no estoy seguro si es lo suficientemente rápido para sus preocupaciones.

EDIT2: Lo he visto recientemente agregó la etiqueta de la tarea. Yo no prefiero mi respuesta si la tarea de la ITF, ya que puede ser de "alto nivel" para una allgorithm-lección

http://download.oracle.com/javase/1.4.2/docs/api/java/util/HashSet.html#add%28java.lang.Object%29

1

O (n) algoritmo: atraviesan la matriz y tratar de entrada de cada elemento una tabla hash/set con número como la tecla hash. si no puede ingresar, entonces eso es un duplicado.

+0

Esto parece ser lo mismo que http://stackoverflow.com/a/4192865. Por favor, solo publique una respuesta si tiene algo nuevo que decir. Y si lo haces, por favor expande tu respuesta. –

+0

2 cosas diferentes en mi publicación: mencionar la complejidad y el hecho de que tienes que 'intentar' insertar el valor desde la perspectiva de .NET. De hecho, el código enumerado en su enlace lanzará una excepción para dups en .NET CLR ya que intentará insertar una clave que ya exista. En .NET, debe usar trygetvalue() antes de la inserción. – Maksood

1
public void printDuplicates(int[] inputArray) { 
    if (inputArray == null) { 
     throw new IllegalArgumentException("Input array can not be null"); 
    } 
    int length = inputArray.length; 

    if (length == 1) { 
     System.out.print(inputArray[0] + " "); 
     return; 
    } 

    for (int i = 0; i < length; i++) { 

     if (inputArray[Math.abs(inputArray[i])] >= 0) { 
      inputArray[Math.abs(inputArray[i])] = -inputArray[Math.abs(inputArray[i])]; 
     } else { 
      System.out.print(Math.abs(inputArray[i]) + " "); 
     } 
    } 
} 
+0

Por favor explique su respuesta. SO existe para educar a las personas, no solo para responder preguntas – Machavity

+0

seguro. La idea principal aquí es usar números en la matriz como índice. Paso 1 - en el signo de cambio de bucle para todos los números debajo de la entrada de índice Array [i]. Paso 0 - verifique si el número es negativo. Si es así, entonces hubo algún otro número que apuntó al elemento actual y lo cambió – smaiakov

+0

@smaiakov, ¿y si el elemento de la matriz en sí es más grande que el tamaño de la matriz? Saldremos de la excepción encuadernada. – Kiran

Cuestiones relacionadas