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

 
Alexey Viktorov:

Wenn also ein Auftrag geschlossen wird, muss er aus dem Array "gestrichen" werden. In solchen Fällen habe ich das Array "in sich selbst" kopiert und die Größe um eins verringert.

In einem solchen Fall würde ich ein nicht vorhandenes Ticket in das Array -1 schreiben, warten, bis alle Aufträge abgeschlossen sind, und dann das gesamte Array löschen (die Arraygröße sollte auf 1 gesetzt werden).

Bei diesem Ansatz wird ein Element des Arrays von Tickets (wenn es keine Reihenfolge gibt) mit nur einer Bedingung geprüft: if(ArrayOfTicket[i] > 0) .....

Imho ist es schneller, als das Feld ständig "auszuschütteln".

 
Igor Makanu:

In diesem Fall würde ich ein nicht vorhandenes Ticket in das Array -1 schreiben, warten, bis alle Bestellungen abgeschlossen sind, und das gesamte Array löschen (Arraygröße = 1).

Bei diesem Ansatz wird ein Element des Arrays von Tickets (wenn es keine Reihenfolge gibt) mit nur einer Bedingung geprüft: if(ArrayOfTicket[i] > 0) .....

Imho ist es schneller, als das Array ständig "auszuschütteln".

Ich versteh das nicht... Was macht es für einen Unterschied, ob man Element für Element löscht oder die Indizes nicht vorhandener Aufträge prüft... das Array wird sowieso geschüttelt...

Wie heute in den Nachrichten gesagt wurde, ist es unmöglich, Geschmack zu patentieren. Floureshers unterscheiden sich nur in der Farbe, schmecken aber alle gleich.

 
Alexey Viktorov:

Ich versteh das nicht... Es macht keinen Unterschied, ob Sie Elemente einzeln löschen oder Indizes von nicht vorhandenen Aufträgen überprüfen wollen... Das Array wird sowieso überlaufen...

Wie heute in den Nachrichten gesagt wurde, ist es unmöglich, Geschmack zu patentieren. Floureshers unterscheiden sich nur in der Farbe, schmecken aber alle gleich.

Das Löschen eines Elements impliziert das Kopieren der verbleibenden Elemente des Arrays, ich lösche keine Elemente des Arrays, ich markiere nicht vorhandene Elemente (Tickets) mit dem Wert -1, und ich lösche ein Array von Tickets, wenn es keine Marktaufträge gibt

Was die Flotationsmarker betrifft, so ist es definitiv richtig, dass es je nach Problem im Prinzip 2 Lösungen bei der Optimierung gibt:

- entweder die Komplexität des Algorithmus erhöhen, aber Speicher und Rechenressourcen des PCs sparen

- oder den Algorithmus vereinfachen und Rechenressourcen sparen, aber Speicherplatz verschwenden

 

Die Prüfsumme ist nicht korrekt, wenn das Array 0 enthält, kann ein Fehler vorliegen

Die Variante von Nikitin funktioniert bei genau diesem Fehler.

Dateien:
456.mq5  20 kb
 
Vladimir Pastushak:

Die Prüfsumme ist nicht korrekt, wenn das Array 0 enthält, kann ein Fehler vorliegen

Die Variante von Nikitin funktioniert genau bei einem solchen Fehler.

Ja, Sie haben Recht. Nur Nikitin warf zusätzlich null Elemente aus. Deshalb sah sein Code aus, als ob er fehlerhaft wäre. Eigentlich ging es darum, die Aufgabe zu lösen, die Sie ursprünglich gestellt hatten.
Wenn Sie seine Prüfung auf Nullelemente dokumentieren, ist das Ergebnis das gleiche:

2018.11.14 13:50:34.481 ArrayDeleteValue (BTCUSD,M15)   вариант Pastushak: Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 133765 микросекунд
2018.11.14 13:50:34.486 ArrayDeleteValue (BTCUSD,M15)   вариант Korotky:   Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 2330 микросекунд
2018.11.14 13:50:34.489 ArrayDeleteValue (BTCUSD,M15)   вариант Fedoseev:  Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 1840 микросекунд
2018.11.14 13:50:34.492 ArrayDeleteValue (BTCUSD,M15)   вариант Semko:     Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 777 микросекунд
2018.11.14 13:50:34.497 ArrayDeleteValue (BTCUSD,M15)   вариант Pavlov:    Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 2818 микросекунд
2018.11.14 13:50:34.503 ArrayDeleteValue (BTCUSD,M15)   вариант Nikitin:   Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 3922 микросекунд
2018.11.14 13:50:34.510 ArrayDeleteValue (BTCUSD,M15)   вариант Vladimir:  Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 4239 микросекунд
2018.11.14 13:50:34.519 ArrayDeleteValue (BTCUSD,M15)   вариант Peter:     Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 7307 микросекунд
2018.11.14 13:50:34.522 ArrayDeleteValue (BTCUSD,M15)   вариант Kuznetsov: Контрольная сумма = 7185.677992388435; элементов - 998993; время выполнения = 683 микросекунд

Auch hier berücksichtigt die Prüfsumme jetzt die Reihenfolge der Elemente, was vorher nicht der Fall war.

Dateien:
 
Ach, vergiss es. Ich trinke gerade mein Bier aus. Ich werde bis Silvester ~25 Liter fertig haben. Das ist es, wovon du sprichst.
 
Nikolai Semko:

Ja, Sie haben Recht. Nur Nikitin warf noch weitere Nullelemente in den Raum. Deshalb sah sein Code aus, als ob er falsch wäre. Eigentlich ging es darum, die Aufgabe zu lösen, die Sie ursprünglich gestellt hatten.
Wenn Sie seine Prüfung auf Nullelemente dokumentieren, ist das Ergebnis das gleiche:

Auch hier berücksichtigt die Prüfsumme jetzt die Reihenfolge der Elemente, was vorher nicht der Fall war.

Übrigens, wenn die Reihenfolge sehr wichtig ist, können Sie ArraySort am Ende meiner Variante hinzufügen und sehen, wie effektiv ArraySort überhaupt ist.

 

Mich interessiert nun eine andere Frage, auf die ich keine Antwort finde.
Vielleicht kann jemand erklären, warum diese Variante von Kuznetsovs Code:

    for(;;)
     {
      while(arr[i]!=x && i<j) i++;
      while(arr[j]==x && i<j) j--;
      if(i<j)
        {
         arr[i++]=arr[j--];
        }
      else break;
     }

funktioniert mehr als doppelt so schnell wie diese, die genau das Gleiche tut:

   while(i<j)
     {
      if(arr[i]==x)
         if(arr[j]!=x) arr[i++]=arr[j--];
      else j--;
      else i++;
     }

Was sind die Wunder des Compilers?
Ist es möglich, dass für ein solches Design:

while(arr[i]!=x && i<j) i++;

Findet der Compiler einen speziellen Assembler-Lookup-Befehl für den Prozessor?
Kennt sich jemand mit modernen Prozessorbefehlen aus?

 
Maxim Kuznetsov:

Übrigens, wenn die Reihenfolge sehr wichtig ist, kann ich ArraySort am Ende meiner Version hinzufügen, zur gleichen Zeit sehen wir, wie effektiv ArraySort überhaupt ist.

Ich habe es ausprobiert. Das ist eine ziemlich kostspielige Funktion. Es ist allerdings einfacher, sie anschließend wegzuwerfen. Alle notwendigen müssen in einer Reihe stehen.


Nikolai Semko:

Ja, Sie haben Recht. Nur Nikitin warf zusätzlich Nullnummern. Deshalb sah sein Code falsch aus. Eigentlich war es die Aufgabe, die Sie ganz am Anfang definiert hatten.
Wenn Sie seine Prüfung auf Nullelemente dokumentieren, ist das Ergebnis das gleiche:

Nahezu jede Funktion kann an sie angepasst werden. Hier ist meine letzte (die rein experimentell war, aber eine der günstigsten zu sein scheint).
template<typename T>
int arrayFilter(T &data[],const T value=NULL)
  {
     int s, _s = s = ArraySize(data);
     bool result = false;
     
     for(int i=0, j=0; i<_s; i++)
     {
          if( data[i] == value || data[i] == NULL )
          {
               result = true;
               s--;
               continue;
          }
          if( result )
               data[j] = data[i];
          j++;
     }
     
     if(s < _s)
          ArrayResize(data, s);
     
     return s;
  }
 
Nikolai Semko:

:

arbeitet mehr als doppelt so schnell wie eine, die genau dasselbe tut:


der Optimierer ist irrelevant - die Vergleiche sind weniger als die Hälfte...

Grund der Beschwerde: