Generische Klassenbibliothek - Bugs, Beschreibung, Fragen, Nutzungsmöglichkeiten und Vorschläge - Seite 8

 

Hier ist der Code zusammen mit dem Eingabefeld. (Es kann für jemanden nützlich sein. Es kann verfeinert werden).

//+------------------------------------------------------------------+
//|                                                   Dictionary.mq5 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      ""
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
#define  Max_possible_collisions    100
#define  Max_letters_in_word        100
#define  All_letters_in_alphabet    255 
//------------------------------------
string Dictionary[Max_possible_collisions][All_letters_in_alphabet][Max_letters_in_word];
//-------------------------------------------------------------------
int OnInit()
  {
//---
   Create_text_box();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectDelete(0,"Text_box");
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
    if(id == CHARTEVENT_OBJECT_ENDEDIT)
      { 
       //-----------------------
       string Text;     
       //---------------------
       ObjectGetString(0,"Text_box",OBJPROP_TEXT,0,Text);
       //-------------------------------------
       Add(Text);
      } 
  }
//+------------------------------------------------------------------+

void Add(string word)
{
 uchar First_letter = (uchar)StringGetCharacter(word,0) - 97;
 //-----------------------
 int All_letters_in_word = StringLen(word);
 //-----------------------
 for(int a1 = 0; a1 < Max_possible_collisions; a1++)
   {
     string word_inside = Dictionary[a1][First_letter][All_letters_in_word];
     //-----------------------   
    if(word_inside == NULL)
      {
       Dictionary[a1][First_letter][All_letters_in_word] = word;
       Print("Your word has been added to our dictionary!");
       break;
      }
    if(word_inside == word)
      {
       Print("This word already exists in our dictionary");
       break;
      } 
   }   
 //------------------------   
}
//--------------------------------------------------------------------+


//--------------------------------------------------------------------
void Create_text_box()
{
  ObjectCreate(0,"Text_box",OBJ_EDIT,0,0,0);
  ObjectSetInteger(0,"Text_box",OBJPROP_XDISTANCE,500);
  ObjectSetInteger(0,"Text_box",OBJPROP_YDISTANCE,250);
  ObjectSetInteger(0,"Text_box",OBJPROP_XSIZE,400);
  ObjectSetInteger(0,"Text_box",OBJPROP_YSIZE,30);
  ObjectSetString(0,"Text_box",OBJPROP_TEXT,"Please enter your word here...");
  ObjectSetString(0,"Text_box",OBJPROP_FONT,"TimesNewRoman");
  ObjectSetInteger(0,"Text_box",OBJPROP_STATE,1);
  //----------------------------------------------
  ObjectSetInteger(0,"Text_box",OBJPROP_FONTSIZE,12);
  ObjectSetInteger(0,"Text_box",OBJPROP_BGCOLOR,clrWhite);
  ObjectSetInteger(0,"Text_box",OBJPROP_COLOR,clrBlack);
  ObjectSetInteger(0,"Text_box",OBJPROP_BORDER_COLOR,clrBlack);
  ObjectSetInteger(0,"Text_box",OBJPROP_ALIGN,ALIGN_CENTER);
  //----------------------------------------------
  ObjectSetInteger(0,"Text_box",OBJPROP_CORNER,CORNER_LEFT_UPPER);
  ObjectSetInteger(0,"Text_box",OBJPROP_ANCHOR,ANCHOR_LEFT_UPPER);  
  //---------------------------------------------- 
}
//----------------------------------------------------------------------- 

Nur aus irgendeinem Grund funktioniert es am vierten Tag vollständig. Bei der fünften wird das Feld nicht angezeigt. Ich habe nach dem Grund gesucht und ihn nicht gefunden.

 
fxsaber:

D.h. man muss für jede Aufgabe das richtige Gleichgewicht zwischen der Größe des Wörterbuchs (RAM) und der Rechenkomplexität der Hash-Funktion (CPU) finden.


Relativ ja.
Wenn die Anzahl der Elemente klein ist, ist die optimale Größe des Wörterbuchs die Anzahl der Elemente zum Quadrat (soweit ich mich aus dem 3-Jahres-Kurs erinnere, aber es ist immer besser, das zu überprüfen).
Wenn eine große Anzahl von Elementen es unmöglich macht, die optimale Größe zu wählen, nehmen sie die Größe des Wörterbuchs um ein Vielfaches größer als die Anzahl der erwarteten Elemente und optimieren die Kollisionsbehandlung, z. B. mit internen Hash-Tabellen für jede der Kollisionen.

Es wird versucht, eine Hash-Tabelle so zu wählen, dass sie so schnell wie möglich durchsucht wird, aber dennoch eine gleichmäßige Verteilung der erhaltenen Ergebnisse über die Größe der Wortliste bietet.
Die Verwendung von Primzahlen in Hashes hängt mit der Gleichmäßigkeit der Verteilung zusammen.

 
Konow-Tag:
Wir mussten die Größe des Arrays erhöhen, weil Großbuchstaben einen anderen Code haben und aus dem Array "herausfallen".

Der Code des Zeichens "A" unterscheidet sich vom Code des Zeichens "a" um genau 32. Dementsprechend haben auch alle anderen die Differenz von 32.

Vielleicht hätte die Array-Größe nicht erhöht und das erste Zeichen ersetzt werden müssen.
 
Alexey Viktorov:

Der Code für das Zeichen "A" unterscheidet sich vom Code für das Zeichen "a" um genau 32. Dementsprechend haben auch alle anderen eine Differenz von 32.

Vielleicht hätte die Array-Größe nicht erhöht und das erste Zeichen ersetzt werden müssen.

Ich stimme zu. Der Algorithmus ist in dieser Hinsicht unvollständig.

Die Arraygröße ist zu groß. Gestern habe ich die Buchstabencodes nicht ganz verstanden.

 
Tag Konow:

Hier ist der Code zusammen mit dem Eingabefeld. (Es könnte für jemanden nützlich sein. Sie können es verfeinern).

Aber es funktioniert perfekt auf 4. Das Feld erscheint nicht auf 5. Ich habe nach dem Grund gesucht und konnte ihn nicht finden.

Noch eine Bemerkung: In Vasiliy's Beispiel wird ein Array erwähnt

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Generische Klassenbibliothek - Fehler, Beschreibungen, Fragen, Besonderheiten der Nutzung, Anregungen

Vasiliy Sokolov, 2017.12.07 14:30

Sehr einfach im assoziativen Array #1

Sehr viele Algorithmen, die in Generic vorgestellt werden, basieren auf assoziativen Arrays oder Wörterbüchern. Es ist auch einer der beiden am häufigsten verwendeten Algorithmen. Ich glaube, ich käme der Wahrheit nahe, wenn ich sagen würde, dass 90 % aller Programmieraufgaben mit Arrays und Dictionaries abgedeckt werden. Bevor wir uns der Praxis zuwenden, wollen wir die Arbeit des Wörterbuchs so klar und einfach wie möglich beschreiben und dabei bewusst einige Details vereinfachen.

Wir werden das Wörterbuch an einem sehr einfachen Beispiel zeigen: einer regulären Wortliste. Nehmen wir an, wir haben nur ein paar Wörter, die alle mit verschiedenen Buchstaben des Alphabets beginnen:

string words[] = {"apple", "cat", "fog", "dog", "walk", "zero"};

Das englische Alphabet umfasst 26 Zeichen. Erstellen wir ein Array mit Strings, das 26 Elemente umfasst:

string dictionary[26];

Wenn wir uns nun darauf einigen, Wörter in Indizes zu speichern, die ihrem Anfangsbuchstaben entsprechen, erhalten wir ein einfaches Wörterbuch. Wir werden von Grund auf neu indizieren. Das Wort "Apfel" wird in unserem Wörterbuch auf dem Index 0 gespeichert, weil das "a" der erste Buchstabe des Alphabets ist, "Katze" auf dem Index 1, "Hund" auf dem Index 3, "Nebel" auf dem Index 4, "Spaziergang" auf dem Index 24 und "Null" auf dem letzten Index 25.

Beachten Sie, dass die Indizes 5 bis 23 nicht verwendet werden. Dies ist eine zusätzliche Speicherverschwendung, aber wir können z.B. sofort auf das Wort "walk" zugreifen, weil wir wissen, dass es, wenn es existiert, bei Index 24 steht.

Lassen Sie uns unser erstes leeres Wörterbuch schreiben:



Und in Ihrem Beispiel.

#define  Max_possible_collisions    100
#define  Max_letters_in_word        100
#define  All_letters_in_alphabet    255 
//------------------------------------
string Dictionary[Max_possible_collisions][All_letters_in_alphabet][Max_letters_in_word];

Wie viel Speicherplatz benötigt ein 3-dimensionales Feld? Und wenn ich die Dimensionalität erhöhen muss?

 
Alexey Viktorov:

Noch ein Hinweis: In Vasiliy's Beispiel wird ein Array erwähnt


Und in Ihrem Beispiel.

Wie viel Speicherplatz benötigt ein 3-dimensionales Feld? Und was, wenn wir die Dimensionalität erhöhen müssen?

Die Größe des Arrays ist zu groß, weil:

1. Ich habe beschlossen, dass ein Wort maximal 100 Buchstaben haben darf. Das ist offensichtlich zu viel. Wir könnten sie auf 30 reduzieren.

2. Auch die Anzahl der möglichen Buchstaben erwies sich als zu hoch. Ich beschloss, so vielen verschiedenen Charakteren wie möglich Platz einzuräumen. Kann reduziert werden.

3. Die Anzahl der "Kollisionen", d. h. die Übereinstimmung von Wörtern anhand des ersten Buchstabens und der Anzahl der Buchstaben im Wort, wird auf 100 festgelegt. Auch das ist zu viel. Sie könnten bis auf 50 runtergehen.


Ich sehe keinen Grund, sie zu erhöhen. Sie können einfach ein Wörterbuch hinzufügen.

 
Tag Konow:

Die Größe des Arrays ist zu groß, weil:

1. Ich habe beschlossen, dass ein Wort maximal 100 Buchstaben haben darf. Das ist eindeutig zu viel des Guten. Sie könnte auf 30 reduziert werden.

2. Auch die Anzahl der möglichen Buchstaben erwies sich als zu hoch. Ich beschloss, so vielen verschiedenen Charakteren wie möglich Platz einzuräumen. Kann reduziert werden.

3. Die Anzahl der "Kollisionen", d. h. die Übereinstimmung von Wörtern anhand des ersten Buchstabens und der Anzahl der Buchstaben im Wort, wird auf 100 festgelegt. Auch das ist zu viel. Sie können sie auf 50 reduzieren.


Ich sehe keinen Grund, die Größe zu erhöhen. Sie können einfach ein weiteres Wörterbuch erstellen.

Die Frage bezieht sich nicht auf das Wörterbuch. Das Wörterbuch ist nur ein Beispiel dafür, wie man einen Algorithmus aufbaut. Es gibt vielleicht bei weitem nicht 100 Artikel wie in deinem Beispiel, sondern 1e10 und mehr... Wie groß ist das Array in einem solchen Fall?

Sammeln Sie zum Beispiel alle verfügbaren Tick-Historien in einem Array. In einer Millisekunde kann es mehr als einen Tick geben, daher kann das Array nicht eindimensional sein... Wie viele Ticks gab es maximal in einer Millisekunde??? Zwei oder fünf??? Welche Dimensionalität sollte das Array in diesem Fall haben??? Wie viel Speicherplatz würde verschwendet werden?

 
Alexey Viktorov:

Sammeln Sie zum Beispiel alle verfügbaren Tick-Historien in einem Array.

Nachdem ich all dies geschrieben hatte, fiel mir ein, dass es keine praktische Aufgabe ist, Zecken so zu speichern, wie es in diesem Thread diskutiert wird. Sie werden nach Zeit sortiert und in einem einfachen Array gespeichert.

Das Gleiche gilt für History Orders/Deals. Und nach HistorySelect zu urteilen, werden sie nach Zeit in einem Array gespeichert. Und ich denke, es gibt (in der derzeitigen Implementierung) nichts, was die Suche nach Datensätzen nach Ticket oder ID ermöglichen würde.

Und das alles nur, weil es im Falle der genannten Geschichte nicht sinnvoll ist, so etwas zu machen. Ein einfaches Array zum Üben ist völlig ausreichend.

Deshalb bin ich an der praktischen Formulierung von Aufgaben im Bereich des Handels interessiert.


Wenn Sie versuchen, HistorySelect zu beschleunigen, bin ich sicher, dass Sie das Problem mit Caching und nicht mit Hashes und Dictionaries gelöst haben.

 
fxsaber:

Nachdem ich all dies geschrieben hatte, fiel mir ein, dass es keine praktische Aufgabe ist, Zecken so zu speichern, wie es in diesem Thread diskutiert wird. Sie werden nach Zeit sortiert und in einem einfachen Array gespeichert.

Das Gleiche gilt für History Orders/Deals. Und nach HistorySelect zu urteilen, werden sie nach Zeit in einem Array gespeichert. Und ich denke, es gibt (in der derzeitigen Implementierung) nichts, was die Suche nach Datensätzen nach Ticket oder ID ermöglichen würde.

Und das alles nur, weil es im Falle der genannten Geschichte nicht sinnvoll ist, so etwas zu machen. Ein einfaches Array zum Üben ist völlig ausreichend.

Deshalb bin ich an der praktischen Formulierung von Aufgaben im Bereich des Handels interessiert.


Wenn Sie HistorySelect beschleunigen, haben Sie es wahrscheinlich mit Caching gelöst, nicht mit Hash-Wörterbüchern.

Das ist kein Argument, aber wenn jemand eine Aufgabe auf diese Weise umsetzen will, dann sollte er sie an Ort und Stelle kennzeichnen...

Jemand denkt, dass es keinen Sinn hat, jemand kann es nicht meistern... Und in beiden Fällen gibt es einfachere Implementierungen. Aber wer weiß, wie sich der Handel "morgen" entwickeln wird... Es ist wahrscheinlich besser, sie zu haben und nicht in Anspruch zu nehmen, als sie zu brauchen, wenn sie nicht vorhanden ist.

 
Alexey Viktorov:

Die Frage bezieht sich nicht auf das Wörterbuch. Das Wörterbuch ist nur ein Beispiel für die Konstruktion eines Algorithmus. Und es kann sein, dass es bei weitem nicht 100 Artikel sind wie in deinem Beispiel, sondern 1e10 und mehr... Wie groß ist das Array in einem solchen Fall?

Sammeln Sie zum Beispiel alle verfügbaren Tick-Historien in einem Array. In einer Millisekunde kann es mehr als einen Tick geben, daher kann das Array nicht eindimensional sein... aber wie viele Ticks gab es höchstens in einer Millisekunde??? Zwei oder fünf??? Welche Dimensionalität sollte das Array in diesem Fall haben??? Wie viel Speicherplatz wird verschwendet?

Ich war dabei, die Aufgabe zu lösen, ein praktisches Wörterbuch zu erstellen.

Zecken oder andere Elemente haben ihre eigenen spezifischen Eigenschaften, die für einen schnellen Zugriff auf den Speicherort erfolgreich indiziert werden können.

Der Kern der Aufgabe, schnell auf Daten zuzugreifen, besteht darin, mehrere klassifizierbare Eigenschaften eines Elements zu identifizieren und sie zu indizieren.

Ein Element wird entnommen, die geeigneten Eigenschaften, von denen man Indizes erhalten kann, werden gefunden, und der Zugriff auf den Speicherort erfolgt über die Indizes.

Wenn die Indizes nicht ausreichen (z. B. können wir den ersten Buchstaben und die Anzahl der Buchstaben indizieren, aber andere Eigenschaften bieten keinen geeigneten Index), führen wir ein direktes Brute-Forcing der Elemente innerhalb des Bereichs um sie herum durch.

Das Prinzip ist universell, die Umsetzung kann variieren.

Grund der Beschwerde: