Ich bin dafür verantwortlich, einen alten VB-Code neu zu schreiben. Ich verstehe, wie es funktioniert, aber ich habe das Gefühl, dass es einen weitaus effizienteren Weg gibt, das zu tun, was sie getan haben. Ich kann einfach nicht herausfinden, was es ist. Hier ist ein erfundenes Beispiel, das in Bezug auf die Datenanforderungen wirklich dem entspricht, was ich tun muss.
Der Benutzer muss den Hersteller, die Marke, das Modell und die Farbe seines Autos in einer grafischen Benutzeroberfläche auswählen. Ich habe eine große Textdatei, die ungefähr so aussieht:
Ford Truck F150 red
Ford Truck F150 blue
Ford Truck F150 black
Ford Truck F150 silver
Ford Truck F250 red
Ford Truck F250 green
Ford Sedan Taurus red
Ford Sedan Taurus green
Ford Sedan Taurus white
Ford...
...
Subaru SUV Forester blue
Subaru SUV Forester red
Subaru SUV Outback Black
Subaru SUV Outback Green
Subaru SUV Outback Blue
Subaru SUV Outback Red
Subaru...
...
etc.
Wenn die erste Auswahl Subaru ist, sollte das zweite Feld (Marke) keine Option zur Auswahl von LKW haben, da keiner der Subarus LKWs sind. Wenn sie Ford, Sedan und Taurus auswählen, sollte das letzte Feld (Farbe) keine Option zur Auswahl von Blau enthalten. Oder schwarz. Oder etwas anderes als rot, grün oder weiß.
Die Leute, die den Code vor mir geschrieben haben, haben sich das ausgedacht (im Python-y-Pseudocode):
def getValidOptions():
items = []
for i from 0 to numRows:
options = getLine().split()
if selectingManufacturer:
if options[0] not in items:
items.append(options[0])
else if selectingMake:
if selectedManufacturer == options[0] and options[1] not in items:
items.append(options[1])
else if selectingModel:
if selectedManufacturer == options[0] and selectedMake == options[1] and options[2] not in items:
items.append(options[2])
else if selectingColor:
if selectedManufacturer == options[0] and selectedMake == options[1] and selectedModel == options[2] and options[3] not in items:
items.append(options[3])
return items
Ich finde das einfach abscheulich, sowohl auf Algorithmus- als auch auf Syntaxebene. Zum einen analysiert es die gesamte Datei, wenn es nur ein paar Zeilen durchlesen muss, wenn es richtig gemacht wird. Um dies noch ineffizienter zu machen, haben meine realen Daten 6 Optionen zur Auswahl und nicht nur 4. Dies speichert auch mehr Daten als nötig, angesichts des Umfangs der Datenverdoppelung.
Ich suche entweder nach einer anderen Methode zum Speichern der Daten in der Datei oder nach einer anderen Methode zum Parsen, um die getValidOptions
Funktion sowohl hübscher als auch effizienter zu gestalten. Gibt es Möglichkeiten, wie ich das tun könnte?
Antworten:
Alle anderen Antworten, die ich lese, scheinen zwei sehr grundlegende Regeln der Softwareentwicklung zu ignorieren:
Klären Sie zuerst die Anforderungen (insbesondere die Leistungs- und Speicheranforderungen).
Halte es einfach, dumm (siehe KISS )
Sie haben "Die Textdatei ist groß" geschrieben, aber nicht zu groß geschrieben. Ich gehe also davon aus, dass an der Größe nichts auszusetzen ist, außer Ihrem Bauchgefühl. Wenn das Laden der Datei nicht zu lange dauert und Ihre IT-Abteilung oder eine andere Person sich nicht über den verschwendeten Speicherplatz beschwert und sich niemand über Probleme bei der Pflege der Datei beschwert, lassen Sie das Dateiformat unverändert. Unterschätzen Sie das nicht Wert der Einfachheit.
Sie beschweren sich auch über die Effizienz des Algorithmus, der eigentlich nicht so effizient ist, wie er sein könnte, aber einen sehr großen Vorteil hat: Er ist hirntot einfach und funktioniert. Wenden Sie keine vorzeitige Optimierung an, solange dies effizient genug ist.
Nehmen wir also an, das Programm funktioniert schnell genug. Zunächst sollten Sie sich fragen, wie Sie den Code in Bezug auf Einfachheit und DRY-Prinzip verbessern können. Und das ist in der Tat ein Punkt, der verbessert werden sollte, da der aktuelle Code nicht trocken ist. In Ihrem Beispiel wird viermal fast derselbe Codeblock getestet, wenn die Optionen auf den "höheren Ebenen" mit der aktuellen Zeile übereinstimmen. Dies führt zu viermal der gleichen Art von "Anhängen" -Aufruf (in Ihrem realen Code tritt die Wiederholung auf mindestens sechsmal, wie du geschrieben hast). Sie können dies leicht vermeiden, indem Sie eine numerische Auswahlstufe einführen oder die bereits ausgewählten Optionen in einer geordneten Liste übergeben. Wenn Sie Ihren Pseudocode verwenden, führt dies zu etwas in der Art von
Dies ist also im Wesentlichen derselbe Algorithmus ohne wiederholten Code mehr.
Da es offensichtlich
getValidOptions
ist, dass mehr als einmal aufgerufen werden muss (mindestens einmal pro Ebene), empfehle ich, nur eine Optimierung anzuwenden (falls dies nicht bereits der Fall ist): Stellen Sie sicher, dass diegetLine
Funktion ihre Daten aus dem Hauptspeicher abruft und nicht Lesen Sie die Datei immer wieder von der Festplatte.quelle
Nun, die Daten, die Sie haben, haben eine baumartige Struktur, wobei Sie für jeden Hersteller einen Baum von Modellen haben und für jedes Modell eine Farbe (und so weiter).
Sie können den Prozess dieser Daten also in zwei Schritten trennen:
Die Baumstruktur kann mit einem sogenannten Hash , einem assoziativen Array oder einem Wörterbuch in Sprachen wie Java, PHP, Javascript oder Python implementiert werden. Mit dieser Struktur haben Sie:
Abhängig von Ihrer Programmiersprache kann dies schneller oder langsamer implementiert werden. Beispielsweise:
Runtime.Serialization.Formatters.Binary.BinaryFormatter
könnte so etwas nützlich sein, aber ich bin kein Experte für die Serialisierung mit VB.Net.Class
, die die Schnittstelle implementiertjava.io.Serializable
.Referenzen :
1: https://dvanderboom.wordpress.com/2008/03/15/treet-implementing-a-non-binary-tree-in-c/
- Eine vollständige Erklärung zum Implementieren eines Baums in C #.
- Suchen Sie nach einem Kommentar, in dem jemand nach der Serialisierung dieses Objekts fragt , und nach der Antwort auf diesen Kommentar.
quelle
tree with an arbitrary number of nodes
Implementierung zu verbringen .Eine einfache Möglichkeit, die Daten zu speichern, besteht darin, sie einfach in eine SQLite-Datenbank zu speichern. SQLite eignet sich im Gegensatz zu den meisten SQL-Datenbanken gut zur Verwendung als Anwendungsdateiformat. Dieser Ansatz hat mehrere Vorteile:
select distinct model where manufacturer='ford' and color = 'red'
. B. ), um Dropdowns zu begrenzen .Dadurch müssen Sie zwar SQL lernen, müssen jedoch kein benutzerdefiniertes Dateiformat erlernen.
quelle
Ich gehe davon aus, dass Sie zufällig auf Zeilen in der Datei zugreifen und die Datei somit als Array von Datensätzen behandeln können. Wenn Sie nicht zufällig auf die Zeilen zugreifen können, ist der Algorithmus, den Sie haben, der beste, den Sie tun können.
Speichern Sie die Daten für einen schnellsten Zugriff in 6 Dateien, wobei jede Datei ein Index für die nächste ist.
Es gibt viele Möglichkeiten, Flatfile-Indizes zu erstellen. Normalerweise verwende ich einen tiefgestellten Bereich. Verwenden Sie bei jeder Auswahl den Bereich, um das Lesen der nächsten Datei einzuschränken.
So würde ich die Indizes für die von Ihnen angegebenen Beispieldaten erstellen.
Natürlich muss die Datei sortiert werden. Ich habe die Zeilen zur Veranschaulichung nummeriert; Die Zeilennummern sollten nicht in der Datei erscheinen.
Um den ersten Index zu erstellen, erstellen Sie einen Datensatz für jede eindeutige Kombination der ersten drei Felder in der Datei. Speichern Sie in jedem Datensatz die erste und letzte Zeilennummer, in der diese Kombination angezeigt wird.
Der zweite Index wird ähnlich aufgebaut, wobei die ersten beiden Felder des ersten Index verwendet werden.
Und die dritte, in diesem Fall die oberste Ebene, der Index.
Ich glaube, ich erkläre das Konzept übermäßig, aber im Allgemeinen erstellen Sie einen Index, indem Sie das letzte Feld löschen und doppelte Datensätze entfernen.
Sie können den Dateispeicherbedarf weiter reduzieren, indem Sie einige redundante Daten entfernen.
Beispielsweise ist der "erste" Index in jedem Indexdatensatz immer eins mehr als der "letzte" Index des vorherigen Datensatzes oder Null, wenn kein vorheriger Datensatz vorhanden ist. Sie müssen also nicht die "ersten" Indizes speichern. Ich lasse sie unten zur Veranschaulichung an Ort und Stelle.
Da Sie nur das letzte Feld in jedem Datensatz verwenden, um die Auswahlliste zu füllen, müssen Sie die anderen Felder nicht speichern.
Die minimale Wiedergabe der Indexkaskade sieht folgendermaßen aus, wobei das Häkchen 'eine Zahl anzeigt, die nicht tatsächlich in der Datei gespeichert ist.
Wenn Sie eine Auswahlliste aus einem Index füllen, verwenden Sie die Indizes "first" und "last" aus der Auswahl des Benutzers im vorherigen Index, um die gelesenen Zeilen zu begrenzen.
Beispiel:
Sie füllen die erste Auswahlliste aus allen
file0.dat
. (Ford, Subaru)Der Benutzer wählt "Ford". Die entsprechenden Indizes sind 0 und 1.
Sie füllen die zweite Auswahlliste aus den Zeilen 0 bis 1 von
file1.dat
. (LKW, Limousine)Der Benutzer wählt "Limousine". Die entsprechenden Indizes sind 2 und 2.
Wie Sie sehen können, müssen Sie zum Zeitpunkt der Auswahl durch den Benutzer, z. B. "Ford", "Limousine", "Taurus", nur die Zeilen 6 bis 8 lesen
file3.dat
, um die vierte Auswahlliste zu füllen.Ich entschuldige mich für die ziemlich lange Beschreibung, aber es ist sehr spät hier und ich habe keine Zeit, eine kurze zu schreiben.
HINZUGEFÜGT: Bei weiterer Überlegung können die Dateien zu einer verkettet werden.
Dies wird genau wie die Version mit mehreren Dateien verwendet, außer dass Sie die erste Dummy-Zeile benötigen, um den ersten Indexbereich zu enthalten.
quelle