it-swarm.com.de

Welche Algorithmen / Datenstrukturen sollte ich "erkennen" und beim Namen kennen?

Ich würde mich gerne als ziemlich erfahrenen Programmierer betrachten. Ich programmiere jetzt seit über 5 Jahren. Meine Schwachstelle ist jedoch die Terminologie. Ich bin Autodidakt, also kenne ich zwar programmieren, aber einige der formaleren Aspekte der Informatik nicht. Was sind also praktische Algorithmen/Datenstrukturen, die ich anhand des Namens erkennen und kennen könnte?

Hinweis: Ich bitte nicht um eine Buchempfehlung zur Implementierung von Algorithmen. Die Implementierung ist mir egal, ich möchte nur erkennen können, wann ein Algorithmus/eine Datenstruktur eine gute Lösung für ein Problem darstellt. Ich bitte mehr um eine Liste von Algorithmen/Datenstrukturen, die ich "erkennen" sollte. Zum Beispiel kenne ich die Lösung für ein Problem wie dieses:

Sie verwalten eine Reihe von Schließfächern mit der Bezeichnung 0-999. Die Leute kommen zu Ihnen, um das Schließfach zu mieten, und kommen dann zurück, um den Schließfachschlüssel zurückzugeben. Wie würden Sie eine Software erstellen, um zu wissen, welche Schließfächer kostenlos sind und welche verwendet werden?

Die Lösung wäre eine Warteschlange oder ein Stapel.

Was ich suche, sind Dinge wie "In welcher Situation sollte ein B-Baum verwendet werden - Welcher Suchalgorithmus sollte hier verwendet werden" usw. Und vielleicht eine kurze Einführung, wie die komplexeren (aber häufig verwendeten) Datenstrukturen/Algorithmen funktionieren.

Ich habe versucht, mir die Wikipedia-Liste von Datenstrukturen und Algorithmen anzusehen, aber ich denke, das ist ein bisschen übertrieben. Also suche ich mehr nach den wesentlichen Dingen, die ich erkennen sollte?

69
Earlz

Eine objektive Antwort:

Während meine erste Antwort auf diese Frage auf meiner empirischen Erfahrung als CS-Student mit baldigem Abschluss und meiner projizierten Meinung über die Art von Menschen beruhte, mit denen ich im CS-Bereich arbeiten wollte. Es gibt tatsächlich eine objektive Antwort (in Bezug auf die subjektiven Meinungen der ACM SIGCSE- und IEEE-Computergesellschaften). Alle 10 Jahre kooperieren die [~ # ~] acm [~ # ~] und die [~ # ~] ieee [~ # ~] Körper an einem gemeinsame Veröffentlichung, in der Vorschläge für einen Lehrplan für Informatikstudenten aufgeführt sind basierend auf Fachwissen über den Stand der Computerindustrie. Weitere Informationen finden Sie unter cs2013.org . Das Komitee veröffentlicht einen Abschlussbericht, in dem die Lehrplanempfehlung aufgeführt ist .

Trotzdem finde ich meine Liste immer noch ziemlich gut.

Ursprüngliche Antwort unten.


Was soll ich wissen?

Minimum

Ich denke, ein erfahrener Programmierer sollte mindestens Grundkenntnisse in Informatik haben. Sicher, Sie können bei vielen Jobs mit nur einer kleinen Teilmenge von Informatik effektiv sein, da CS auf einer soliden Community basiert und der Fokus von die meisten beruflichen Positionen. Außerdem werden sich viele Menschen nach dem Studium weiter spezialisieren. Ich denke jedoch auch nicht, dass dies eine Entschuldigung dafür ist, nicht mit grundlegenden CS-Kenntnissen vertraut zu sein.

Um die Titelfrage zu beantworten, sollte ein CS-Student (die Grundlage für einen erfahrenen Programmierer) nach seinem Abschluss Folgendes wissen:

Datenstrukturen

  • Darstellung der Maschinendaten
    • Eins, Zweierkomplement und verwandte Arithmetik
    • Wörter, Zeiger, Gleitkomma
    • Bitzugriff, Verschiebung und Manipulation
  • Verknüpfte Listen
  • Hash-Tabellen (Karten oder Wörterbücher)
  • Arrays
  • Bäume
  • Stapel
  • Warteschlangen
  • Grafiken
  • Datenbanken

Algorithmen

  • Sortierung:
    • Bubble Sort (um zu wissen, warum es schlecht ist)
    • Sortieren durch Einfügen
    • Zusammenführen, sortieren
    • Schnelle Sorte
    • Radix-Stilsortierungen, Zählsortierung und Bucket-Sortierung
    • Heap Sort
    • Bogo und Quantensortierung (=
  • Suche:
    • Lineare Suche
    • Binäre Suche
    • Tiefe Erste Suche
    • Breite erste Suche
  • String-Manipulation
  • Wiederholung
  • Baumdurchquerung
  • List Traversal
  • Hashing-Funktionen
  • Konkrete Implementierung einer Hash-Tabelle, eines Baums, einer Liste, eines Stapels, einer Warteschlange, eines Arrays und eines Satzes oder einer Sammlung
  • Planungsalgorithmen
  • Durchlaufen und Manipulieren des Dateisystems (auf der Inode oder einer gleichwertigen Ebene).

Designmuster

  • Modularisierung
  • Fabrik
  • Baumeister
  • Singleton
  • Adapter
  • Dekorateur
  • Fliegengewicht
  • Beobachter
  • Iterator
  • Zustandsmaschine]
  • Model View Controller
  • Threading- und parallele Programmiermuster

Paradigmen

  • Imperativ
  • Objektorientierter
  • Funktionell
  • Deklarativ
  • Statische und dynamische Programmierung
  • Datenmarkierung

Komplexitätstheorie

  • Komplexitätsräume
  • Berechenbarkeit
  • Normale, kontextfreie und universelle Turingmaschine vervollständigen Sprachen
  • Reguläre Ausdrücke
  • Zählen und grundlegende Kombinatorik

Darüber hinaus

Wenn Sie mit dem oben Gesagten vertraut sind, sollten Sie in der Lage sein, das geeignete Muster, den Algorithmus und die Datenstruktur für ein bestimmtes Szenario zu identifizieren, um später in Ihrer Frage auf die Fragen einzugehen. Sie sollten jedoch erkennen, dass es oft keine beste Lösung gibt. Manchmal müssen Sie möglicherweise das kleinere von zwei Übeln auswählen oder einfach zwischen zwei gleichermaßen praktikablen Lösungen wählen. Aus diesem Grund benötigen Sie das Allgemeinwissen, um Ihre Wahl gegen Ihre Kollegen verteidigen zu können.

Hier einige Tipps für Algorithmen und Datenstrukturen:

  • Die binäre Suche kann (und sollte) nur für sortierte Daten verwendet werden.
  • Radix-Sortierungen sind fantastisch, aber nur, wenn endliche Klassen von Dingen sortiert werden.
  • Bäume sind für fast alles gut, ebenso wie Hash-Tabellen. Die Funktionalität einer Hash-Tabelle kann extrapoliert und verwendet werden, um viele Probleme auf Kosten der Effizienz zu lösen.
  • Arrays können verwendet werden, um die meisten übergeordneten Datenstrukturen zu sichern. Manchmal ist eine "Datenstruktur" nicht mehr als eine clevere Mathematik für den Zugriff auf Positionen in einem Array.
  • Die Wahl der Sprache kann den Unterschied zwischen dem Herausziehen der Haare oder dem Durchsegeln eines Problems ausmachen.
  • Die Tabelle ASCII und ein Array mit 128 Elementen bilden eine implizite Hash-Tabelle (=)
  • Reguläre Ausdrücke können viele Probleme lösen, aber sie können nicht zum Parsen von HTML verwendet werden .
  • Manchmal ist die Datenstruktur genauso wichtig wie der Algorithmus.

Einige der oben genannten Punkte scheinen keine Hirngespinste zu sein, andere scheinen vage zu sein. Wenn Sie möchten, dass ich näher darauf eingehe, kann ich das. Ich hoffe jedoch, dass Sie bei einer konkreteren Frage wie "Entwerfen einer Funktion, die die Anzahl der Vorkommen jedes Zeichens in einem String zählt" auf den Tipp zu ASCII) schauen Tabellen- und 128-Element-Arrays bilden saubere implizite Hash-Tabellen für die Antwort.

Basierend auf diesen Ideen werde ich eine Antwort auf das in Ihrer Frage beschriebene Schließfachproblem vorschlagen.


Antwort auf das in Ihrer Frage gestellte Problem.

Dies ist vielleicht nicht die beste Antwort auf Ihre Frage, aber ich denke, es ist eine interessante, die nichts zu Komplexes erfordert. Und es wird sicherlich die zeitliche Komplexität der Verwendung einer Warteschlange oder eines Stapels übertreffen, für die lineare Zeit erforderlich ist, um festzustellen, ob ein Schließfach frei ist oder nicht.

Sie haben 0-999 Schließfächer. Da Sie nun eine feste Anzahl von Schließfächern haben, können Sie sich leicht eine Hashing-Funktion ohne Kollisionen im Bereich von 0 bis 1999 vorstellen. Diese Funktion ist einfach h(x) = x mod 1000. Erstellen Sie nun [konzeptionell] eine Hash-Tabelle mit Ganzzahlschlüsseln und dem Inhalt eines 1000-Elemente-Char-Arrays als Ihre Werte. Wenn ein Kunde Wenn Sie das Schließfach 78 für die Verwendung reservieren möchten, setzen Sie einfach 78 in die Hash-Funktion (Rückgabe 78) und fügen Sie diese Zahl dann zum Basiszeiger des Arrays hinzu. Dabei wird ein wahrer Wert an der Stelle gespeichert, auf die der Versatzwert zeigt. Wenn Sie überprüfen müssen, ob 78 verwendet wird, lesen Sie einfach den an diesem Speicherort gespeicherten Wert und prüfen Sie ihn mit true.

Diese Lösung arbeitet in konstanter Zeit für Suchvorgänge und Speicherung im Gegensatz zu einer Protokoll (n) -Zeitspeicherung und -suche bei einer Prioritätswarteschlange, die von einem Binärbaum unterstützt wird. Die Beschreibung ist absichtlich ausführlich, sodass Sie sehen können, wie die höheren Konzepte zu einem effizienten Algorithmus zusammengefasst werden.

Nun könnten Sie sich fragen, was wäre eine Prioritätswarteschlange nicht besser, wenn ich alle verfügbaren Schließfächer kennen müsste? Wenn in der Prioritätswarteschlange k Schließfächer verfügbar sind, werden k Schritte ausgeführt, wenn alle Schließfächer durchlaufen werden. Abhängig von Ihrer Implementierung der Prioritätswarteschlange müssen Sie möglicherweise Ihre Prioritätswarteschlange neu erstellen, wenn Sie sich alles ansehen. Dies würde k * log (k): (k <1000) Schritte erfordern. In der Array-Lösung müssen Sie nur ein Array mit 1000 Elementen iterieren und prüfen, welche geöffnet sind. Sie können der Implementierung auch eine verfügbare oder verwendete Liste hinzufügen, um nur k Zeit einzuchecken.

78
David Cowden

Das Algorithm Design Manual von Steven S. Skiena scheint die Quelle zu sein, nach der Sie suchen. Der zweite Teil ist eine klassifizierte Liste von Problemen mit einer Überprüfung der zugehörigen Algorithmen. Es gibt eine Webversion .

6
AProgrammer

Es gibt kein "sollte". A. Machen Sie sich mit den grundlegenden Komplexitätsklassen (linear, logarithmisch usw.) vertraut. B. Stellen Sie fest, dass Sie mit einem einfachen Array fast alles tun können, wie Sie es mit einer ausgefallenen Datenstruktur wie einem B-Baum können. Der Trick bei der Auswahl der geeigneten Struktur/des geeigneten Algorithmus besteht darin, die Leistung, die erwartete Eingabegröße und die Komplexität der Implementierung in Einklang zu bringen.

Dann gibt es abstrakte, aber immens nützliche Dinge (obwohl die Nützlichkeit nicht sofort offensichtlich ist): Zustandsmaschinen, Graphentheorie, Konvexitätstheorie (lineare Programmierung usw.).

4
zvrba

Das MIT veröffentlicht kostenlose Vorlesungsunterlagen, Videos, Aufgaben und Prüfungsunterlagen für Einführung in Algorithmen . Die Vorlesungstitel listen die behandelten Algorithmen/Datenstrukturen auf.

Dies ist ein Peer-Review Konsens darüber, was Sie wissen sollten. Es ist wahrscheinlich auch eine großartige Lernressource.

3
MarkJ