Löschen eines Arrays mit definierten Element(en) - Seite 29

 
Sergey Dzyublik:
Im Wesentlichen verwenden Sie eine statische HashSet-Datenstruktur mit einem anfänglichen Array von Daten, um Kollisionen aufzulösen.
Aber die Umsetzung ist einfach augenöffnend...

Anstatt eine Funktion ("FindValueInSortArray") mit 100-500 unnötigen Parametern aufzurufen, wird in der Regel eine Klasse verwendet, in der diese Parameter als Felder der Klasse fungieren (Gewinn bei der Übergabe von Parametern, wenn der Compiler nicht erraten hat, dass sie implizit inline sind).
Wenn es notwendig ist, ein Paar von Arrays derselben Größe und mit demselben Verwendungszweck zu verwenden ( int p1[]; int p2[];), wird in der Regel ein Strukturarray verwendet (Vorteil des Indexzugriffs, geringere Gefahr von Cache-Fehlern).

Ja, ich weiß. Ich stimme zu, ich habe selbst Angst vor meiner eigenen Umsetzung. Aber mein Ziel ist der Algorithmus, nicht die Implementierung. Wie man so schön sagt - "auf den Knien zusammengebaut" (etwa anderthalb Stunden), um die Korrektheit und Geschwindigkeit des Algorithmus zu überprüfen. Erinnern Sie sich, dass dieser Thread diskutiert (und ich zitiere) "der schnellste Weg, um ein Array von Junk-Werte spülen".

Allerdings habe ich eine Menge Beschwerden über meinen eigenen Algorithmus, denn er ist bei weitem nicht universell. Ich sehe Möglichkeiten, den Algorithmus zu verbessern, aber der Code wird sehr viel komplexer werden. Schade um die Zeit.

ZZY HashSet zuerst gehört, weil ich nicht stark in der Theorie bin. Ich weiß sehr wohl, dass ich nichts Neues erfunden habe und dass alles vor mir erfunden wurde. :)) Der Vorteil dieses Algorithmus ist offensichtlich, wenn die zu löschenden Elemente gleichmäßig verteilt sind. Wenn die Verteilung sehr unterschiedlich von der Gleichverteilung ist, kann diese Implementierung in Bezug auf die Geschwindigkeit anderen, die bereits in diesem Zweig existieren, unterlegen sein.

 
Taras Slobodyanik:

die Berechnung des Betrags auf CRC32 geändert)

Ich danke Ihnen. Natürlich ist es korrekter.

Aber soweit ich weiß, hat der Wechsel zu CRC32 keine Fehler aufgedeckt. :)

 

Ich möchte Ihnen sagen, dass ich persönlich von den Fähigkeiten moderner Computer und insbesondere von MQL5 beeindruckt bin.

Immerhin dauert es nur 1/40 Sekunden(!!!), um in einem Array mit einer Million Elementen nach etwa tausend verschiedenen Werten zu suchen, diese zu löschen (etwa 100.000 Zellen) und das bereinigte Array neu zu packen.

 
Optimiert
Dateien:
 
nicholi shen :

Es ist alles genial einfach! :))

Allerdings verbraucht dieser Algorithmus unkontrollierbar viel Speicherplatz.

Wenn Sie also zum Beispiel Folgendes ersetzen

arr[i]= rand ()% 10000 ;
....
Value2[i]= rand ()% 10000 ;

mit .

arr[i]= rand ()* rand ();
....
Value2[i]= rand ()* rand ();

ist die Situation völlig anders:

2018.11 . 19 23 : 25 : 57.593 ArrayDeleteValue21 (NZDUSD,D1)  вариант nicholi shen: Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -  603551 микросекунд
2018.11 . 19 23 : 25 : 57.980 ArrayDeleteValue21 (NZDUSD,D1)  вариант Nikitin     : Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -  383847 микросекунд
2018.11 . 19 23 : 25 : 58.043 ArrayDeleteValue21 (NZDUSD,D1)  вариант fan9        : Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -   61414 микросекунд
2018.11 . 19 23 : 25 : 58.074 ArrayDeleteValue21 (NZDUSD,D1)  вариант Semko       : Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -   28430 микросекунд
Dateien:
 
Hinzufügen von ArrayDeleteValue zu einigen weiteren Personen im Projekt, Rechte zum Bearbeiten. Wen ich vorher übersehen habe.
 
Nikolai Semko:

Ich danke Ihnen. Das ist sicherlich der richtige Weg.

Aber soweit ich weiß, hat der Wechsel zu CRC32 keine Fehler aufgedeckt. :)

Ja, aber jetzt können diejenigen, die mit eigenen Augen das Ergebnis eines einzigen Algorithmus gesehen haben, dafür sorgen, dass andere das gleiche Ergebnis erhalten.)

 
Bitte schreiben Sie zu diesem Thema. Kein Schimpfen oder Fluchen. Ich danke Ihnen.
 
nicholi shen:

Keine schlechte Idee, aber wenn es negative Werte in einem Array oder Vektor, erhalten Sie ein Array außerhalb des Bereichs Fehler

Außerdem kann die Größe eines Arrays mit Filterflags2 147 483 647 erreichen, was zu viel ist

Natürlich können Sie die Größe um das 32-fache reduzieren, indem Sie die Einstellung von 32 BOOL-Variablen durch eine Bitmaske wie diese ersetzen:

int array_filter(int &a[],const int &b[]) //nicholishen
{
   int e=ArraySize(a);
   int c[];
   int d =b[ArrayMaximum(b)]+1;
   ArrayResize(c, b[ArrayMaximum(b)]/32 + 1);
   ArrayInitialize(c, 0);
   int i=0;
   int ii=0;
   while(i<ArraySize(b))
   {     
     ii=b[i]/32;
     c[ii]|=(1<<(b[i]-(ii*32)));
     i++; 
   } 
   
   int g=0, h=0, f=0;
   for(g=0; g<e; g++){
      f = a[g];
      ii=f/32;
      if(f >= d || !(c[ii] & (1<<(f-(ii*32)))) )
      {
         a[h]=f;
         h++;
      }
   }
   return ArrayResize(a, h);
}


aber es wäre immer noch zu groß und die Geschwindigkeit würde um etwa die Hälfte sinken.

 
Nikolai Semko:

Es ist alles genial einfach! :))

Allerdings verbraucht dieser Algorithmus unkontrollierbar viel Speicherplatz.

Wenn Sie also zum Beispiel Folgendes ersetzen

mit .

ist die Situation ganz anders:

Ihre Version ist auch gut, aber leider haben Sie auch einen Schwachpunkt. Unter "häuslichen" Bedingungen, d. h. bei kleinen Arrays der Größe ~100 und kleinen Vektoren ~5-10

Ihr Algorithmus wird langsamer sein als alle anderen hier vorgestellten, obwohl der Unterschied in Mikrosekunden so gering ist, dass er wahrscheinlich nicht ins Gewicht fällt, aber bei größeren Arrays ist er der beste.

P.S. Ich denke, dass die Funktion universell sein sollte, es ist notwendig, in ihr einige verschiedene Algorithmen zu kombinieren, die je nach Eingangsdaten ausgewählt werden.