Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Themengebiete » Informatik in der Schule » C# Sortieren von Werten » Antwort erstellen » Hallo Gast [Anmelden|Registrieren]

Antwort erstellen
Benutzername: (du bist nicht eingeloggt!)
Thema:
Nachricht:

HTML ist nicht erlaubt
BBCode ist erlaubt
Smilies sind erlaubt
Bilder sind erlaubt

Smilies: 21 von 33
smileWinkDaumen hoch
verwirrtAugenzwinkerngeschockt
Mit ZungeGottunglücklich
Forum Kloppebösegroßes Grinsen
TanzentraurigProst
TeufelSpamWillkommen
LehrerLOL HammerZunge raus
Hilfe 
aktuellen Tag schließen
alle Tags schließen
fettgedruckter Textkursiver Textunterstrichener Text zentrierter Text Hyperlink einfügenE-Mail-Adresse einfügenBild einfügen Zitat einfügenListe erstellen CODE einfügenPHP CODE farbig hervorheben
Spamschutz:
Text aus Bild eingeben
Spamschutz

Die letzten 10 Beiträge
Karlito

genau
InformaTiger

Wenn ich jetzt aber ein Set verwende kann ich mir dann die if-Abfrage sparen, oder? Er nimmt Werte ja nur einmalig auf oder hab ich da etwas falsch verstanden?

Mfg
InformaTiger
Karlito

Ich denke ja, es sollte schneller werden.

Gruß,

Karlito
InformaTiger

Hallo,
entschuldigt bitte, dass ich mich nicht mehr gemeldet habe. Ich hatte in letzter Zeit nur etwas Stress unglücklich . Dann sollte ich also ein Set verwenden und die Geschichte wäre von der Preformance her, gegessen?

Mfg
InformaTiger
Karlito

Hallo euler, hallo InformaTiger,

auch wenn man es vielleicht so biegen kann, dass eine Liste effizient wird, so würde ich mich darauf verlassen, das die Implementierung des Sets effiizienter ist. Schließlich ist sie für genau diesen Zweck gebaut. Ansonsten würde ich eine Liste, welche optimiert ist selbst implementieren.
Mich würde an der Stelle mal ein Vergleich Interessieren: 1 Mio eindeutige Einfügevorgänge für eine Liste und das Selbe für ein Set. Ich würde darauf tippen, dass das Set gewinnt. Spätestens beim Speicherverbrauch.

Sorry, wenn die Diskussion hier zu weit geht.

Gruß,

Karlito
eulerscheZahl

Guter Einwand, Karlito.

Noch ein Vorschlag, wie es auch mit einer einfachen List effizient geht: da bereits nach kategorie sortiert ist, reicht es, den letzten Eintrag zu prüfen:
code:
1:
2:
if (kategorien[kategorien.Count - 1] != arr[4*i + 2])
    kategorien.Add(arr[4 * i + 2]);
Karlito

Hallo,

wenn es Kategorien nicht doppelt geben kann, warum verwendet ihr dann nicht ein Set? Sets entsprechen mathematischen Mengen und sind so gebaut, dass sie effizient ermöglichen Elemente nur einmalig aufzunehmen (In Mengen kann es ja auch keine Doppelten geben). Bei einem HashSet hat man idealisiert konstante Laufzeit, d.h. jeder Einfügevorgang (mit Prüfung auf doppelte) und jeder Suchvorgang (contains()) dauert idealisiert eine konstante Zeit, unabhängig von der Anzahl der Elemente (in der Realität klappt das nicht ganz). Problem ist, dass ein HashSet nicht sortiert ist.
Für sortierte Mengen gibt es noch das SortedSet. Ich denke das hat dann logarithmische Laufzeit (auch sehr gut). Jedenfalls spart man sich die Prüfung auf doppelte und das selektive Einfügen.

Gruß,

Karlito
InformaTiger

Also wenn ich das richtig verstanden habe, was du zu bemängeln hast dann ist das Prinzip dasselbe wie das hier:

code:
1:
2:
3:
4:
5:
int index = kategorien.IndexOf(arr[4 * i + 2]);
if (index < 0)
{
    kategorien.Add(arr[4 * i + 2]);
}


Nur, dass du mit einer anderen Methode den index bekommst als ich in dem Beispiel. Sortiert ist meine Liste ja ohnehin schon, da ich sie mit dem ORDER BY Kommando sortiert aus der Datenbank erhalte. Wobei ich sagen muss dass der zweite Code von dir noch effizienter ist.

code:
1:
2:
3:
4:
if (!kategorien.Contains(arr[4 * i + 2]))
{
    kategorien.Add(arr[4 * i + 2]);
}


Mfg
InformaTiger
eulerscheZahl

Wenn du schon so fragst, das gefällt mir nicht:
code:
1:
2:
kategorien.Add(arr[4 * i + 2]);
kategorien = kategorien.Distinct().ToList();

Ich weiß nicht, wie viele Einträge du bei deiner SQL-Abfrage erhältst, aber die musst du alle zwischenspeichern, um dann den Großteil wieder zu löschen.

Ich würde das hier bevorzugen:
code:
1:
2:
if (kategorien.Contains(arr[4*i + 2])
    kategorien.Add(arr[4*i + 2]);


Je nach Anzahl der Kategorien könnte es Sinn machen, die Liste sortiert zu halten, das beschleunigt das Suchen.
Das ginge so:
code:
1:
2:
3:
4:
5:
6:
        int index = dinosaurs.BinarySearch("Coelophysis");
        if (index < 0)
        {
            dinosaurs.Insert(~index, "Coelophysis");
        }

(von Microsoft)
InformaTiger

So... dank der Hilfe meines Bruders ist es mir jetzt endlich gelungen. Der Code dazu sieht so aus:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
            Database_Request request = new Database_Request();
            string[] arr = request.ReadFromTable("SELECT tbl_values.Datum, tbl_values.Wert, tbl_categories.Name, tbl_categories.Farbe FROM tbl_values INNER JOIN tbl_categories ON tbl_categories.ID = tbl_values.FK_Kategorie WHERE MONTH(Datum) = " + DateTime.Now.Month + " ORDER BY tbl_categories.Name, tbl_values.Datum;");
            List<DBEntry> entries = new List<DBEntry>();
            List<string> kategorien = new List<string>();

            for (int i = 0; i < arr.Length / 4; i++)
            {
                entries.Add(new DBEntry(DateTime.Parse(arr[4 * i]), int.Parse(arr[4 * i + 1]), arr[4 * i + 2], arr[4 * i + 3]));
                kategorien.Add(arr[4 * i + 2]);
            }

            kategorien = kategorien.Distinct().ToList();

            g.Restore(gs);

            int count = 0;

            for (int i = 0; i < kategorien.Count; i++)
            {
                int old;
                old = count;
                count += entries.Count(c => c.kategorie == kategorien[i]);

                if (count - old == 1)
                {
                    g.DrawLine(new Pen(new SolidBrush(ColorTranslator.FromHtml('#' + entries[old].farbe.ToLower())), 2.0f), (entries[old].datum.Day + 0.5f) * del, entries[old].bewertung * del, (entries[old].datum.Day + 1) * del, entries[old].bewertung * del);
                }
                else
                {
                    for (int j = old; j < count - 1; j++)
                    {
                        g.DrawLine(new Pen(new SolidBrush(ColorTranslator.FromHtml('#' + entries[j].farbe.ToLower())), 2.0f), (entries[j].datum.Day + 0.5f) * del, entries[j].bewertung * del, (entries[j + 1].datum.Day + 0.5f) * del, entries[j + 1].bewertung * del);
                    }
                             
                }
                
            }


Die Variable old speichert jeweils den letzten Stand und sorgt dafür dass Einträge die alleine stehen und noch keinen Referenzpunkt haben auch angezeigt werden. Wichtig war auch bei der SQL Anweisung eine sekundäre Sortierung hinzuzufügen: ORDER BY tbl_categories.Name, tbl_values.Datum;

PS: wenn du noch was verbessern wüsstest, bitte einfach nur machen Augenzwinkern

Danke für deine Hilfe!

Mfg
InformaTiger

InformaTiger hat dieses Bild (verkleinerte Version) angehängt:
selfmonitor.gif

Es sind weitere Beiträge zu diesem Thema vorhanden. Klicken Sie hier, um sich alle Beiträge anzusehen.