Cancellare un array di elementi definiti - pagina 3

 
Vladimir Pastushak:

Il compito principale è quello di cancellare l'array di valori definiti.

Questo non può essere il compito principale. Cosa viene raccolto in questa matrice e come viene utilizzato?

 
Stanislav Korotky:

Beh, non è una cosa seria. Se tirare gli elefanti per risolvere questo particolare piccolo problema, citerei STL::remove(array, value).

Questo è molto serio e fondamentale. MQL è solo verboso. Terribilmente.

Operatori fondamentali come filter (che in TC è, filtrare), map (mappatura), fold (collassare, riassumere)
dovrebbe essere implementato immediatamente, senza fare domande. Ed essere ottimizzato.

 
Maxim Kuznetsov:

Questo è molto serio e fondamentale. MQL è solo verboso. È orribile.

Operatori fondamentali come filter (che in TC è filtraggio), map (mappatura), fold (somma)
dovrebbero essere implementati subito, senza domande. Ed essere ottimizzato.

Il punto è che tirare una dipendenza così grassa ("fondamentale") per un piccolo compito non ha senso. Se per scrivere tutto saggiamente e rifattorizzare l'intero progetto - allora, naturalmente, ma non è l'essenza della domanda originale.

 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Pulire un array da elementi specificati

Dmitry Fedoseev, 2018.11.12 23:05

void DelEl(double & a[],double v){
   int sz=ArraySize(a);
   for(int i=sz-1;i>=0;i--){
      if(a[i]==v){
         sz--;
         for(int j=i;j<sz;j++){
            a[j]=a[j+1];
         }
      }
   }
   ArrayResize(a,sz);
}


Questa è una specie di vergogna...©

1. Confrontare variabili di tipo double tramite ==, per dirla tutta, non è comico;
2. La complessità del codice è O(n^2), e la complessità peggiore per questo problema con una sequenza di input non ordinata dovrebbe essere O(n);
3. Il codice non funziona, perché quando la funzione viene effettivamente utilizzata, è impossibile determinare quanti valori validi contiene l'array restituito:

void DelEl(double & a[],double v){
   int sz=ArraySize(a);
   for(int i=sz-1;i>=0;i--){
      if(a[i]==v){
         sz--;
         for(int j=i;j<sz;j++){
            a[j]=a[j+1];
         }
      }
   }
   ArrayResize(a,sz);
}


int OnStart(){
   double arr[] = {3, 5, 5, 3, 3, 5, 5, 3};
   double v = 3;
   
   ArrayPrint(arr);
   DelEl(arr, v);
   ArrayPrint(arr);
   
   return INIT_SUCCEEDED;
}


Risultato dell'esecuzione:

2018.11.13 00:35:33.355 Test123 (EURUSD,H1)     3.00000 5.00000 5.00000 3.00000 3.00000 5.00000 5.00000 3.00000
2018.11.13 00:37:08.495 Test123 (EURUSD,H1)     5.00000 5.00000 5.00000 5.00000 5.00000 5.00000 5.00000 3.00000

I valori non validi sono evidenziati in rosso, non sono mai stati rimossi dall'array.

 
Sergey Dzyublik:


Questa è una specie di vergogna...©

1. Non è bello confrontare le variabili di tipo doppio tramite ==, per dirla tutta;
2. La complessità del codice è O(n^2), e la complessità del caso peggiore per questo problema con una sequenza di input non ordinata dovrebbe essere O(n);
3. Il codice non funziona, perché quando la funzione viene effettivamente utilizzata, è impossibile determinare quanti valori validi contiene l'array restituito:


Risultato dell'esecuzione:

I valori non validi che non sono mai stati rimossi dall'array sono evidenziati in rosso.

Jublik? Così sia. Confrontare le variabili di tipo doppio è abbastanza comico se non vengono calcolate prima del confronto.

Imparare la matematica. E la vergogna?

 
Sergey Dzyublik:


Questa è una specie di vergogna...©

1. Confrontare le variabili di tipo double con == è, a dir poco, non comico;
2. La complessità del codice è O(n^2), e la complessità peggiore per questo problema con una sequenza di input non ordinata dovrebbe essere O(n);
3. Il codice non funziona, perché quando la funzione viene effettivamente utilizzata, è impossibile determinare quanti valori validi contiene l'array restituito:


Risultato dell'esecuzione:

I valori non validi che non sono mai stati rimossi dall'array sono evidenziati in rosso.

Non essere assurdo. Devo spiegarti il tuo errore o puoi indovinarlo da solo? Non è affatto difficile...

Tre punti, tre recinti. In realtà, no, solo due paddock.

ps, ma ho fiducia in te.

ps2 ecco il risultato se usate la funzione correttamente:


 

Così va meglio:

void DelEl2(double & a[],double v){
   int sz=ArraySize(a);
   int i=0;   
   int j=0;
   for(;i<sz;i++){ 
      if(a[i]!=v){
         a[j]=a[i];
         j++;
      }
   }
   ArrayResize(a,j);
}
 
Dmitry Fedoseev:

Così va meglio:

Dimitri, lascia che ti sconvolga - v è anche un array.

E comunque, è tutto un mucchio di sciocchezze.

 
Алексей Тарабанов:

Dimitri, lascia che ti sconvolga - v è anche un array.

E in generale, tutto questo è una totale assurdità.

Se v è un array, non è un problema. Ma il fatto che sia una sciocchezza è più probabile. Non ho mai sentito il bisogno di risolvere questo compito.

 

Se è una gara di velocità, offrirò anche la mia variante:

int ArrayDeleteVal(int &a[],const int val) // вариант Semko
  {
   int size=ArraySize(a);
   int i=0,start,s,count;
   while(i<size && a[i]!=val) i++; // ищем первый элемент массива со значением val
   start=i; i++;
   while(i<size && a[i]==val) i++; // ищем элемент массива со значением, не равным val
   s=i; i++;
   while(true)
     {
      while(i<size && a[i]!=val) i++; // ищем элемент массива со значением val
      count=i-s;
      if(count>6) { ArrayCopy(a,a,start,s,count); start+=count;} // если нужно скопировать более 6 элементов, то имеет смысл воспользоваться ArrayCopy
      else for(; s<i; start++,s++) a[start]=a[s];                // иначе простой цикл
      if(i==size) break;
      i++;
      while(i<size && a[i]==val) i++; // ищем элемент массива со значением, не равным val
      if(i<size) s=i; else break;
      i++;
     }
   if(start<size) ArrayResize(a,start); else start=size;
   return(start);
  }

Ho scritto uno script di test per tutte le varianti.
Ecco il risultato per un array di 1 000 000 elementi (circa 1000 valori in più):

2018.11.12 19:50:02.965 ArrayDeleteValue (EURUSD,D1)    вариант Pastushak: Контрольная сумма = 495654091; элементов - 998983; время выполнения = 156457 микросекунд
2018.11.12 19:50:02.969 ArrayDeleteValue (EURUSD,D1)    вариант Korotky: Контрольная сумма = 495654091; элементов - 998983; время выполнения = 2319 микросекунд
2018.11.12 19:50:02.972 ArrayDeleteValue (EURUSD,D1)    вариант Fedoseev: Контрольная сумма = 495654091; элементов - 998983; время выполнения = 1810 микросекунд
2018.11.12 19:50:02.974 ArrayDeleteValue (EURUSD,D1)    вариант Semko: Контрольная сумма = 495654091; элементов - 998983; время выполнения = 785 микросекунд
Chi è il prossimo? :))
Peter, Awww....
File: