Cum pot elimina duplicatele dintr-o matrice C #?

Am lucrat cu o matrice string [] în C# care este returnată dintr-un apel de funcție. Aș putea să arunc o colecție Generic , dar mă întrebam dacă există o modalitate mai bună de a face acest lucru, posibil folosind o matrice temp.

Care este cel mai bun mod de a elimina duplicatele dintr-o matrice C #?

0
fr hi bn
Utilizați metoda Extensie distinctă.
adăugat autor kokos, sursa
@ Vitim.us Nu. În cazul meu, nu este chiar o matrice, ci o listă . Accept orice răspuns care face treaba. Poate că este un șoc de a face pe hârtie.
adăugat autor AngryHacker, sursa
Intr-adevar. Este mai distractiv atunci când matricea este deja sortată - în acest caz se poate face în loc în timpul O (n).
adăugat autor David Airapetyan, sursa

20 răspunsuri

Ați putea folosi o interogare LINQ pentru a face acest lucru:

int[] s = { 1, 2, 3, 3, 4};
int[] q = s.Distinct().ToArray();
0
adăugat
Rețineți că puteți folosi un IEqualityComparer ca parametru, cum ar fi .Distinct (StringComparer.OrdinalIgnoreCase) pentru a obține un set distinct de șiruri de caractere distincte.
adăugat autor justis, sursa
Distinct onoruri ordine originale de elemente?
adăugat autor asyrov, sursa

Dacă ar fi trebuit să o sortați, atunci ați putea implementa un fel care să elimine și duplicatele.

Ucide două păsări cu o singură piatră.

0
adăugat
Cum sortează eliminarea duplicatelor?
adăugat autor Danyal Ozair, sursa

Următorul cod testat și funcțional va elimina duplicatele dintr-o matrice. Trebuie să includeți spațiul de nume 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]);
}

Ai putea să înfrunți asta într-o funcție dacă vrei.

0
adăugat

NOTĂ: NU este testat!

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

Ar putea face ceea ce aveți nevoie ...

EDIT Argh!!! beaten to it by rob by under a minute!

0
adăugat
Rob nu te-a bătut la nimic. Folosește ArrayList, în timp ce folosești Lista. Versiunea ta este mai bună.
adăugat autor Doug S, sursa

Adăugați toate șirurile într-un dicționar și obțineți ulterior proprietatea Keys. Acest lucru va produce fiecare șir unic, dar nu neapărat în aceeași ordine în care au fost introduse informațiile inițiale.

Dacă aveți nevoie ca rezultatul final să aibă aceeași ordine ca și intrarea inițială, atunci când luați în considerare prima apariție a fiecărui șir, utilizați următorul algoritm:

  1. Aveți o listă (ieșire finală) și un dicționar (pentru a verifica duplicatele)
  2. Pentru fiecare șir din intrare, verificați dacă există deja în dicționar
  3. Dacă nu, adăugați-l atât în ​​dicționar, cât și în listă

În final, lista conține prima apariție a fiecărui șir unic.

Asigurați-vă că luați în considerare lucruri precum cultura și altele asemenea, atunci când construiți dicționarul dvs., pentru a vă asigura că manipulați duplicatele cu litere accentuate corect.

0
adăugat

Here is the HashSet approach:

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

Din păcate, această soluție necesită, de asemenea, cadrul .NET 3.5 sau mai recent, deoarece HashSet nu a fost adăugat până în acea versiune. De asemenea, puteți utiliza array.Distinct() , care este o caracteristică a LINQ.

0
adăugat
Aceasta probabil că nu va păstra ordinea inițială.
adăugat autor Hamish Grubijan, sursa

Acest lucru ar putea depinde de cât de mult doriți să proiectați soluția - dacă matricea nu va fi niciodată atât de mare și nu vă interesează să sortați lista ați putea încerca ceva similar cu următorul:

    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));
    }
0
adăugat
Ar trebui să utilizați Listă în loc de ArrayList.
adăugat autor Doug S, sursa
List myStringList = new List();
foreach (string s in myStringArray)
{
    if (!myStringList.Contains(s))
    {
        myStringList.Add(s);
    }
}

Acesta este O (n ^ 2) , care nu contează pentru o listă scurtă care va fi umplute într-un combo, dar ar putea fi rapid o problemă pentru o colecție mare.

0
adăugat

Poate hashset care nu stochează elemente duplicate și ignoră în tăcere cererile de adăugat duplicate.

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

    Console.WriteLine(textWithDuplicates.Count());  
    var letters = new HashSet(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(array);
    Console.WriteLine(distinctArray.Count());

    foreach (int i in distinctArray) Console.Write(i + ",");
}
0
adăugat

Aici este o abordare O (n * n) care utilizează spațiul O (1) .

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';
    }
}

Abordările hash/linq de mai sus sunt cele pe care le-ați folosi în general în viața reală. Cu toate acestea, în interviuri, ei doresc, de obicei, să pună unele constrângeri, de ex. un spațiu constant care exclude hash-ul sau nu există api - care exclude utilizarea LINQ .

0
adăugat
Cum poate vreodată să utilizeze spațiul O (1), când trebuie să stocați întreaga listă? Începând cu un sortare inplace, poți să faci O (nlogn) timp și O (n) memorie, cu mult mai puțin cod.
adăugat autor Thomas Ahle, sursa
Ce te face să crezi că stochează întreaga listă? Într-adevăr, o face pe loc. Și, deși nu este o condiție în întrebare, codul meu menține ordinea caracterelor din șirul original. Sortare va elimina acest lucru.
adăugat autor Sesh, sursa

- Aceasta este Întrebarea interviului întrebată de fiecare dată. Acum i-am făcut codificarea.

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();
        }
0
adăugat
Nu trebuie să faceți o complexitate a timpului O (n * 2) pentru această întrebare.
adăugat autor Danyal Ozair, sursa
Ar trebui să utilizați tipul de îmbinare
adăugat autor nfgallimore, sursa

Următoarea bucată de cod încearcă să elimine duplicatele dintr-un ArrayList, deși aceasta nu este o soluție optimă. Mi sa dat această întrebare în timpul unui interviu pentru a elimina duplicatele prin recursivitate și fără a utiliza un al doilea/temp aristolist:

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);
            }
        }
0
adăugat
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 ");
    }
}
0
adăugat

Tested the below & it works. What's cool is that it does a culture sensitive search too

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

0
adăugat

Acest cod 100% elimina valorile duplicate dintr-un tablou [ca am folosit un [i]] ..... Poti sa-l converti in orice limbaj OO ..... :)

for(int i=0;i
0
adăugat

Soluție simplă:

using System.Linq;
...

public static int[] Distinct(int[] handles)
{
    return handles.ToList().Distinct().ToArray();
}
0
adăugat
nu aveți nevoie de ToList() ...
adăugat autor jHilscher, sursa

puteți folosi acest cod când lucrați cu 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]);
0
adăugat
public static int RemoveDuplicates(ref int[] array)
{
    int size = array.Length;

   //if 0 or 1, return 0 or 1:
    if (size  < 2) {
        return size;
    }

    int current = 0;
    for (int candidate = 1; candidate < size; ++candidate) {
        if (array[current] != array[candidate]) {
            array[++current] = array[candidate];
        }
    }

   //index to count conversion:
    return ++current;
}
0
adăugat

Mai jos este o logică simplă în java pe care traversați elementele de matrice de două ori și dacă vedeți același element pe care îi alocați zero și nu atingeți indicele elementului pe care îl comparați.

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

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

    for(int b=0;b
0
adăugat
  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(ref outputArray, outputArray.Length + 1);
                            outputArray[outputArray.Length-1] = inputArray[i];
                        }
            }
            return outputArray;
        }
0
adăugat
explicați răspunsul dvs., vă rog.
adăugat autor Badiparmagi, sursa