Doppelte Zahlen in array finden
- VB.NET
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von ~blaze~.
-
-
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
-
-
-
-
TG22997 schrieb:
ob es sich in der selben line wiederholen kann
Ja, kann es, aber NUR BEI STRINGS. Andere Werte haben keine Leerzeichen und können somit nicht öfter vorkommen.
456 456
Die Items werden also nur "Reihenweise" vergleicht./nicht getestet -
wo ist dann das problem jedes item zu vergleichen... mit distinct kenn ich mich nicht aus weil ich schon lange
nicht mehr intensiv programmiert habe. Aber hier mein Lösungsversuch mittels zwei schleifen:
Ist natürlich unsauber ich weiß... Aber habe ich noch nie gebraucht und wie gesagt muss ich mich
mal mit Distinct auseinandersetzen ;D
Würde mich auch darüber freuen wenn mir jemand Distinct erklärt.
MfG Tim -
Enumerable.Distinct(Of TSource)
Gibt mithilfe des Standardgleichheitsvergleichs zum Vergleichen von Werten unterschiedliche Elemente aus einer Sequenz zurück.
msdn.microsoft.com/de-de/library/vstudio/bb348436.aspx
Mit Distinct (Englisch für "eindeutig") werden doppelte Elemente in einer "Liste" über Board geschmissen.
Mein Code ruft die Länge des eindeutigen Arrays ab (also dem von Distinct()) & die des regulären Arrays.
Dann werden beide Längen verglichen: Wenn das eindeutige Array weniger Elemente als das Reguläre hat, dann sind folglich Doppelte Elemente vorhanden,/nicht getestet -
Vielen Dank für eure Hilfe.
@RodFromGermany: mit array.sort ist das array bereits sortiert.
Was ist denn der Unterschied zwischen deinen beiden Varianten?
@rotherford:ich habe den Code ein bisschen gekürzt und angepasst; funktioniert:
@TG22997: meine Auflistung sieht so aus: 1; 2; 3; 3; 4; 5; 6
Gruß Ludwig -
Hi
performant sind beide genannten Methoden nicht. Sortierung ist immer so ein Thema, aber beide Methoden führen eine Menge unnötiger Operationen aus. Wie wär's mit folgendem?
VB.NET-Quellcode
- Public Module CustomExtensions
- <Runtime.CompilerServices.Extension()> _
- Public Function IsDistinct(Of T)(ByVal enumeration As IEnumerable(Of T)) As Boolean
- Dim previous As ICollection(Of T) = New LinkedList(Of T)()
- For Each v As T In enumeration
- If previous.Contains(v) Then Return False
- previous.Add(v)
- Next
- Return True
- End Function
- <Runtime.CompilerServices.Extension()> _
- Public Function IsDistinct(Of T)(ByVal enumeration As IEnumerable(Of T), ByVal comparer As IEqualityComparer(Of T)) As Boolean
- Dim previous As ICollection(Of T) = New LinkedList(Of T)()
- For Each v As T In enumeration
- For Each c As T In previous
- If comparer.Equals(v, c) Then Return False
- Next
- previous.Add(v)
- Next
- Return True
- End Function
- End Module
Bisschen Hintergrundwissen: Bei einer geringen Anzahl von Elementen fällt der Performanceschub zwar nicht ins Gewicht, aber für große dafür ggf. sehr stark, da wirklich nur die nötigsten Operationen ausgeführt werden. Man könnte es theoretisch auch ohne Pufferung rein auf der übergebenen Enumeration machen. Ist halt nicht sichergestellt, dass der Enumerator performant implementiert ist.
Wenn man die Performance noch weiter steigern möchte, kann man auch noch den Hashcode verwenden, um die Menge der zu vergleichenden Elemente weiter einzuschränken. Das erfordert allerdings, dass die Elemente ihren Hashcode während dem Aufruf nicht ändern.
Hab's noch mal mit dem Dictionary ergänzt. Hat mich jetzt grad' mal interessiert:
Spoiler anzeigen VB.NET-Quellcode
- Public Module CustomExtensions
- <Runtime.CompilerServices.Extension()> _
- Public Function IsDistinct(Of T)(ByVal enumeration As IEnumerable(Of T)) As Boolean
- Dim previous As ICollection(Of T) = New LinkedList(Of T)()
- For Each v As T In enumeration
- If previous.Contains(v) Then Return False
- previous.Add(v)
- Next
- Return True
- End Function
- <Runtime.CompilerServices.Extension()> _
- Public Function IsDistinct(Of T)(ByVal enumeration As IEnumerable(Of T), ByVal comparer As IEqualityComparer(Of T)) As Boolean
- Dim previous As ICollection(Of T) = New LinkedList(Of T)()
- For Each v As T In enumeration
- For Each c As T In previous
- If comparer.Equals(v, c) Then Return False
- Next
- previous.Add(v)
- Next
- Return True
- End Function
- <Runtime.CompilerServices.Extension()> _
- Public Function IsDistinctQuick(Of T)(ByVal enumeration As IEnumerable(Of T)) As Boolean
- Dim clist As ICollection(Of T) = Nothing
- Dim previous As Dictionary(Of Integer, ICollection(Of T)) = New Dictionary(Of Integer, ICollection(Of T))
- Dim hashcode As Integer
- For Each v As T In enumeration
- hashcode = v.GetHashCode()
- If previous.TryGetValue(hashcode, clist) Then
- If clist.Contains(v) Then Return False
- Else
- clist = New LinkedList(Of T)()
- previous.Add(hashcode, clist)
- End If
- clist.Add(v)
- Next
- Return True
- End Function
- <Runtime.CompilerServices.Extension()> _
- Public Function IsDistinctQuick(Of T)(ByVal enumeration As IEnumerable(Of T), ByVal comparer As IEqualityComparer(Of T)) As Boolean
- Dim clist As ICollection(Of T) = Nothing
- Dim previous As Dictionary(Of Integer, ICollection(Of T)) = New Dictionary(Of Integer, ICollection(Of T))
- Dim hashcode As Integer
- For Each v As T In enumeration
- hashcode = comparer.GetHashCode(v)
- If previous.TryGetValue(hashcode, clist) Then
- For Each p As T In clist
- If comparer.Equals(v, p) Then Return False
- Next
- Else
- clist = New LinkedList(Of T)()
- previous.Add(hashcode, clist)
- End If
- clist.Add(v)
- Next
- Return True
- End Function
- End Module
Gruß
~blaze~Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „~blaze~“ ()
-
-
LudwigM schrieb:
Was ist denn der Unterschied zwischen deinen beiden Varianten?Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
Zwischen dem IsDistinct und IsDistinctQuick ist übrigens ein echt großer Unterschied in der Performance. Hab' ein paar einfache Tests mit Random durchlaufen lassen und die Unterschiede sind echt gravierend. Der 1. Code hat bei 100000 Strings knapp 26 Sekunden gebraucht, der 2. nur 0,12. Das Dictionary selber liegt halt (fast) in O(1), während LinkedList.Contains in O(n) liegt. Da bei der 2. Methode nur die Elemente mit gleichem Hashcode in eine gemeinsame Liste gespeichert werden, müssen entsprechend nur sehr wenige Elemente verglichen werden. Nachteil am Dictionary ist halt der erhöhte Speicherbedarf und der Overhead bei großen Eingaben.
Gruß
~blaze~ -
-
Jep, wobei man häufig auch ein "Workaround" finden kann. Häufig hilft's zum Beispiel wenn man die Hashcodes "umorganisiert" (zumindest bei meinem eigenen theoretischen Dictionary :P, weiß nicht, wie das Framework-Dictionary intern arbeitet). Also zum Beispiel eine bijektive Abbildung für den Hashcode finden, sodass die Aufteilung in 4 Bytes zur Indizierung in den Hashcode-Tabellen so ausfällt, dass die Anzahl der Elemente in der Tiefe möglichst hoch ist, aber in der Breite eher gering.
Bei dem großen Unterschied muss ich allerdings sagen, dass ich die quick-Methode bei großen Listen bevorzuge.
Gruß
~blaze~
-
Ähnliche Themen
-
Problem mit meinem Lotto System
ReisenderHippie - - Multimedia- und Spieleprogrammierung
-
6 Benutzer haben hier geschrieben
- rotherford (4)
- Fortender (4)
- ~blaze~ (3)
- RodFromGermany (2)
- Gast (2)
- Artentus (1)