it-swarm.com.de

Schnelle Möglichkeiten, um Duplikate in einer Liste <> in C # zu vermeiden

Mein C # -Programm generiert zufällige Zeichenfolgen aus einem bestimmten Muster. Diese Zeichenfolgen werden in einer Liste gespeichert. Da keine Duplikate erlaubt sind, mache ich das so:

List<string> myList = new List<string>();
for (int i = 0; i < total; i++) {
  string random_string = GetRandomString(pattern);
  if (!myList.Contains(random_string)) myList.Add(random_string);
}

Wie Sie sich vorstellen können, funktioniert dies für mehrere Hundert Einträge. Aber ich stehe vor der Situation, mehrere Millionen Zeichenketten zu generieren. Und mit jedem hinzugefügten String wird die Suche nach Duplikaten immer langsamer.

Gibt es schnellere Möglichkeiten, um Duplikate zu vermeiden?

28
Robert Strauch

Verwenden Sie eine Datenstruktur, die viel effizienter bestimmen kann, ob ein Element vorhanden ist, nämlich ein HashSet. Unabhängig von der Anzahl der Elemente im Satz kann ermittelt werden, ob sich ein Element zu einer konstanten Zeit im Satz befindet.

Wenn Sie wirklich stattdessen die Elemente in einem List benötigen oder die Elemente in der resultierenden Liste in der Reihenfolge benötigen, in der sie generiert wurden, können Sie die Daten in beiden a speichern Liste und ein Hashset; Hinzufügen des Elements zu beiden Sammlungen, wenn es derzeit nicht in HashSet vorhanden ist.

44
Servy

Benutze nicht List<>. Verwenden Dictionary<> oder HashSet<> stattdessen!

9
catfood

Der einfachste Weg ist, dies zu benutzen:

myList = myList.Distinct().ToList();

Dies würde zwar das einmalige Erstellen der Liste und das anschließende Erstellen einer neuen Liste erfordern. Ein besserer Weg könnte sein, Ihren Generator im Voraus zu machen:

public IEnumerable<string> GetRandomStrings(int total, string pattern)
{
    for (int i = 0; i < total; i++) 
    {
        yield return GetRandomString(pattern);
    }
}

...

myList = GetRandomStrings(total, pattern).Distinct().ToList();

Wenn Sie nicht über einen Index auf Elemente zugreifen müssen, können Sie die Effizienz wahrscheinlich noch weiter verbessern, indem Sie ToList löschen und nur IEnumerable verwenden.

8
p.s.w.g

Sie könnten ein HashSet<string> wenn die Reihenfolge nicht wichtig ist:

HashSet<string> myHashSet = new HashSet<string>();
for (int i = 0; i < total; i++) 
{
   string random_string = GetRandomString(pattern);
   myHashSet.Add(random_string);
}

Die HashSet-Klasse bietet leistungsstarke Set-Operationen. Ein Set ist eine Sammlung, die keine doppelten Elemente enthält und deren Elemente in keiner bestimmten Reihenfolge vorliegen.

MSDN

Oder wenn die Reihenfolge wichtig ist , würde ich die Verwendung eines SortedSet (nur .net 4.5) empfehlen.

6
DGibbs

dies ist keine gute Methode, aber eine Art schnelle Lösung. Prüfen Sie mit einem Bool, ob in der gesamten Liste doppelte Einträge vorhanden sind.

bool containsKey;
string newKey;

    public void addKey(string newKey){

         foreach(string key in MyKeys){
           if(key == newKey){
             containsKey = true;
          }
         }

      if(!containsKey){
       MyKeys.add(newKey);
     }else{
       containsKey = false;
     }

    }
1
Amir Javed

Mit einer Hashtabelle können Sie schneller prüfen, ob ein Element vorhanden ist als eine Liste.

0
Zdravko Danev

Hast du es versucht:

myList = myList.Distinct()
0
jdehlin