2008-08-13 11 views
172

He estado trabajando con una matriz string[] en C# que se devuelve de una llamada a función. Podría lanzar a una colección Generic, pero me preguntaba si habría una mejor manera de hacerlo, posiblemente usando una matriz temporal.¿Cómo elimino los duplicados de una matriz de C#?

¿Cuál es la mejor manera de eliminar los duplicados de una matriz C#?

+0

hecho.Es más divertido cuando la matriz ya está ordenada, en ese caso se puede hacer in situ en el tiempo O (n). –

+0

@ Vitim.us No. En mi caso, ni siquiera es una matriz, sino una lista . Acepto cualquier respuesta que haga el trabajo. Tal vez, es un shock tener que hacerlo en papel. – AngryHacker

+4

Utilice el método de extensión Distinct. – kokos

Respuesta

351

Usted podría utilizar una consulta LINQ para hacer esto:

int[] s = { 1, 2, 3, 3, 4}; 
int[] q = s.Distinct().ToArray(); 
+17

Tenga en cuenta que puede usar un IEqualityComparer como parámetro, como '.Distinct (StringComparer.OrdinalIgnoreCase)' para obtener un conjunto distinto de cadenas insensibles a mayúsculas y minúsculas. – justis

+0

¿Distinct honra el orden original de los elementos? – asyrov

11

Si usted necesita para solucionar el problema, entonces se podría aplicar un género que también elimina los duplicados.

Mata dos pájaros de un tiro, entonces.

+2

¿Cómo elimina la clasificación los duplicados? –

4

Agrega todas las cuerdas a un diccionario y conseguir las llaves de la propiedad después. Esto producirá cada cadena única, pero no necesariamente en el mismo orden en que las ingresó originalmente.

Si necesita que el resultado final tenga el mismo orden que la entrada original, cuando considera la primera ocurrencia de cada cadena , utiliza el algoritmo siguiente lugar:

  1. tener una lista (salida final) y un diccionario (para comprobar si hay duplicados)
  2. para cada cadena en la entrada, compruebe si existe en el diccionario ya
  3. Si no, agréguelo al diccionario y a la lista

Al final, la lista contiene la primera ocurrencia de cada cadena única.

Asegúrese de que se tiene en cuenta cosas como la cultura y como en la construcción de su diccionario, para asegurarse de que usted maneja correctamente duplicados con letras acentuadas.

7

La siguiente probado y código de trabajo será eliminar duplicados de una matriz. Debe incluir el espacio de nombres System.Collections.

string[] sArray = {"a", "b", "b", "c", "c", "d", "e", "f", "f"}; 
var sList = new ArrayList(); 

for (int i = 0; i < sArray.Length; i++) { 
    if (sList.Contains(sArray[i]) == false) { 
     sList.Add(sArray[i]); 
    } 
} 

var sNew = sList.ToArray(); 

for (int i = 0; i < sNew.Length; i++) { 
    Console.Write(sNew[i]); 
} 

Puede envolver esto en una función si lo desea.

8

Esto podría depender de la cantidad que desea para diseñar la solución - si la matriz es nunca va a ser muy grande, y que no se preocupan por la clasificación de la lista es posible que desee probar algo similar a lo siguiente:

public string[] RemoveDuplicates(string[] myList) { 
     System.Collections.ArrayList newList = new System.Collections.ArrayList(); 

     foreach (string str in myList) 
      if (!newList.Contains(str)) 
       newList.Add(str); 
     return (string[])newList.ToArray(typeof(string)); 
    } 
+4

Debe usar List en lugar de ArrayList. –

3

NOTA: No se ha probado!

string[] test(string[] myStringArray) 
{ 
    List<String> myStringList = new List<string>(); 
    foreach (string s in myStringArray) 
    { 
     if (!myStringList.Contains(s)) 
     { 
      myStringList.Add(s); 
     } 
    } 
    return myStringList.ToString(); 
} 

podría hacer lo que necesita ...

EDITAR Argh !!! ¡golpeado por robar por debajo de un minuto!

+0

Rob no te ganó a nada. Está usando ArrayList, mientras usas List. Tu versión es mejor –

49

Aquí es el enfoque HashSet<string>:

public static string[] RemoveDuplicates(string[] s) 
{ 
    HashSet<string> set = new HashSet<string>(s); 
    string[] result = new string[set.Count]; 
    set.CopyTo(result); 
    return result; 
} 

Por desgracia, esta solución también requiere .NET framework 3.5 o posterior ya que HashSet no se agregó hasta esa versión. También puede usar array.Distinct(), que es una característica de LINQ.

+10

Esto probablemente no conservará el orden original. –

5
List<String> myStringList = new List<string>(); 
foreach (string s in myStringArray) 
{ 
    if (!myStringList.Contains(s)) 
    { 
     myStringList.Add(s); 
    } 
} 

Esta es O (n^2), que no importa para una lista corta que va a ser metido en un combo, pero podría ser rápidamente ser un problema en una gran colección.

4

Aquí es una enfoque O (n * n) que utiliza O (1) espacio.

void removeDuplicates(char* strIn) 
{ 
    int numDups = 0, prevIndex = 0; 
    if(NULL != strIn && *strIn != '\0') 
    { 
     int len = strlen(strIn); 
     for(int i = 0; i < len; i++) 
     { 
      bool foundDup = false; 
      for(int j = 0; j < i; j++) 
      { 
       if(strIn[j] == strIn[i]) 
       { 
        foundDup = true; 
        numDups++; 
        break; 
       } 
      } 

      if(foundDup == false) 
      { 
       strIn[prevIndex] = strIn[i]; 
       prevIndex++; 
      } 
     } 

     strIn[len-numDups] = '\0'; 
    } 
} 

El de hash/LINQ enfoques anteriores son la que se uso general en la vida real. Sin embargo, en las entrevistas generalmente quieren poner algunas restricciones, p. espacio constante que descarta el hash o no interna api - que descarta usar LINQ.

+0

¿Cómo puede usar el espacio O (1) cuando tiene que almacenar toda la lista? Al comenzar con una ordenación en el lugar, puede hacer O (nlogn) tiempo y O (n) memoria, con mucho menos código. –

+0

¿Qué le hace pensar que está almacenando toda la lista? De hecho, está haciendo en el lugar. Y aunque no es una condición en la pregunta, mi código mantiene el orden de los caracteres en la cadena original. La clasificación eliminará eso. – Sesh

4

El siguiente fragmento de código intenta eliminar duplicados de un ArrayList, aunque esta no es una solución óptima. Me pidieron esta pregunta durante una entrevista para eliminar duplicados a través de la repetición, y sin necesidad de utilizar un segundo ArrayList/temp:

private void RemoveDuplicate() 
{ 

ArrayList dataArray = new ArrayList(5); 

      dataArray.Add("1"); 
      dataArray.Add("1"); 
      dataArray.Add("6"); 
      dataArray.Add("6"); 
      dataArray.Add("6"); 
      dataArray.Add("3"); 
      dataArray.Add("6"); 
      dataArray.Add("4"); 
      dataArray.Add("5"); 
      dataArray.Add("4"); 
      dataArray.Add("1"); 

      dataArray.Sort(); 

      GetDistinctArrayList(dataArray, 0); 
} 

private void GetDistinctArrayList(ArrayList arr, int idx) 

{ 

      int count = 0; 

      if (idx >= arr.Count) return; 

      string val = arr[idx].ToString(); 
      foreach (String s in arr) 
      { 
       if (s.Equals(arr[idx])) 
       { 
        count++; 
       } 
      } 

      if (count > 1) 
      { 
       arr.Remove(val); 
       GetDistinctArrayList(arr, idx); 
      } 
      else 
      { 
       idx += 1; 
       GetDistinctArrayList(arr, idx); 
      } 
     } 
5
protected void Page_Load(object sender, EventArgs e) 
{ 
    string a = "a;b;c;d;e;v"; 
    string[] b = a.Split(';'); 
    string[] c = b.Distinct().ToArray(); 

    if (b.Length != c.Length) 
    { 
     for (int i = 0; i < b.Length; i++) 
     { 
      try 
      { 
       if (b[i].ToString() != c[i].ToString()) 
       { 
        Response.Write("Found duplicate " + b[i].ToString()); 
        return; 
       } 
      } 
      catch (Exception ex) 
      { 
       Response.Write("Found duplicate " + b[i].ToString()); 
       return; 
      } 
     }    
    } 
    else 
    { 
     Response.Write("No duplicate "); 
    } 
} 
4

Tal hashset que no almacenar elementos duplicados y silenciosamente ignorar las solicitudes para añadir duplicados.

static void Main() 
{ 
    string textWithDuplicates = "aaabbcccggg";  

    Console.WriteLine(textWithDuplicates.Count()); 
    var letters = new HashSet<char>(textWithDuplicates); 
    Console.WriteLine(letters.Count()); 

    foreach (char c in letters) Console.Write(c); 
    Console.WriteLine(""); 

    int[] array = new int[] { 12, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 }; 

    Console.WriteLine(array.Count()); 
    var distinctArray = new HashSet<int>(array); 
    Console.WriteLine(distinctArray.Count()); 

    foreach (int i in distinctArray) Console.Write(i + ","); 
} 
3

Probado el siguiente & funciona. Lo bueno es que se hace una búsqueda sensible a la cultura también

class RemoveDuplicatesInString 
{ 
    public static String RemoveDups(String origString) 
    { 
     String outString = null; 
     int readIndex = 0; 
     CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo; 


     if(String.IsNullOrEmpty(origString)) 
     { 
      return outString; 
     } 

     foreach (var ch in origString) 
     { 
      if (readIndex == 0) 
      { 
       outString = String.Concat(ch); 
       readIndex++; 
       continue; 
      } 

      if (ci.IndexOf(origString, ch.ToString().ToLower(), 0, readIndex) == -1) 
      { 
       //Unique char as this char wasn't found earlier. 
       outString = String.Concat(outString, ch);     
      } 

      readIndex++; 

     } 


     return outString; 
    } 


    static void Main(string[] args) 
    { 
     String inputString = "aAbcefc"; 
     String outputString; 

     outputString = RemoveDups(inputString); 

     Console.WriteLine(outputString); 
    } 

}

--AptSenSDET

6

- Esto se Pregunta De la Entrevista pide cada vez. Ahora hice su codificación.

static void Main(string[] args) 
{  
      int[] array = new int[] { 4, 8, 4, 1, 1, 4, 8 };    
      int numDups = 0, prevIndex = 0; 

      for (int i = 0; i < array.Length; i++) 
      { 
       bool foundDup = false; 
       for (int j = 0; j < i; j++) 
       { 
        if (array[i] == array[j]) 
        { 
         foundDup = true; 
         numDups++; // Increment means Count for Duplicate found in array. 
         break; 
        }      
       } 

       if (foundDup == false) 
       { 
        array[prevIndex] = array[i]; 
        prevIndex++; 
       } 
      } 

      // Just Duplicate records replce by zero. 
      for (int k = 1; k <= numDups; k++) 
      {    
       array[array.Length - k] = '\0';    
      } 


      Console.WriteLine("Console program for Remove duplicates from array."); 
      Console.Read(); 
     } 
+1

No debe hacer una complejidad de tiempo O (n * 2) para esta pregunta. –

+0

Debe usar la clase de combinación – nfgallimore

3

Este código 100% Remover valores duplicados de una matriz [como antes a [i]] ..... se puede convertir en cualquier lenguaje OO ..... :)

for(int i=0;i<size;i++) 
{ 
    for(int j=i+1;j<size;j++) 
    { 
     if(a[i] == a[j]) 
     { 
      for(int k=j;k<size;k++) 
      { 
       a[k]=a[k+1]; 
      } 
      j--; 
      size--; 
     } 
    } 

} 
3

solución simple:

using System.Linq; 
... 

public static int[] Distinct(int[] handles) 
{ 
    return handles.ToList().Distinct().ToArray(); 
} 
+1

, no necesita 'ToList()' ... – jHilscher

1

puede utilizar este código cuando trabajo con un ArrayList

ArrayList arrayList; 
//Add some Members :) 
arrayList.Add("ali"); 
arrayList.Add("hadi"); 
arrayList.Add("ali"); 

//Remove duplicates from array 
    for (int i = 0; i < arrayList.Count; i++) 
    { 
     for (int j = i + 1; j < arrayList.Count ; j++) 
      if (arrayList[i].ToString() == arrayList[j].ToString()) 
       arrayList.Remove(arrayList[j]); 
1
public static int RemoveDuplicates(ref int[] array) 
{ 
    int i = 0;  
    int n = array.Length; 
    if (n > 0) 
    { 
     int v = array[0]; 
     for (int j = 1; j < n; ++j) 
     { 
      if (v != array[j]) 
      { 
       v = array[++i] = array[j]; 
      } 
     } 

     // Index to number: 
     ++i; 
    } 

    return i; 
} 
0

A continuación se muestra una lógica simple en java recorre los elementos de la matriz dos veces y si ve algún elemento igual le asigna cero además de que no toca el índice del elemento que está comparando.

import java.util.*; 
class removeDuplicate{ 
int [] y ; 

public removeDuplicate(int[] array){ 
    y=array; 

    for(int b=0;b<y.length;b++){ 
     int temp = y[b]; 
     for(int v=0;v<y.length;v++){ 
      if(b!=v && temp==y[v]){ 
       y[v]=0; 
      } 
     } 
    } 
} 
0
private static string[] distinct(string[] inputArray) 
     { 
      bool alreadyExists; 
      string[] outputArray = new string[] {}; 

      for (int i = 0; i < inputArray.Length; i++) 
      { 
       alreadyExists = false; 
       for (int j = 0; j < outputArray.Length; j++) 
       { 
        if (inputArray[i] == outputArray[j]) 
         alreadyExists = true; 
       } 
         if (alreadyExists==false) 
         { 
          Array.Resize<string>(ref outputArray, outputArray.Length + 1); 
          outputArray[outputArray.Length-1] = inputArray[i]; 
         } 
      } 
      return outputArray; 
     } 
+1

explique su respuesta, por favor. – Badiparmagi

Cuestiones relacionadas