Funzione - Metodo per ordinare un array di strutture. Premio 10$

 

Ciao a tutti, c'è una funzione scritta da fxsaber

template <typename T>                                       
void ArrayReindex( T &Array[], const double &TmpSort[][2] )
{                         
  T TmpArray[];
  
  for (int x = ::ArrayResize(TmpArray, ::ArrayRange(TmpSort, 0)) - 1; x >= 0; x--)
    TmpArray[x] = Array[(int)(TmpSort[x][1] + 0.1)];
    
  ::ArraySwap(Array, TmpArray);
              
  return;     
}             

// Сортировка массива структур и указателей на объекты по (под-) полю/методу.
#define  ArraySortStruct(ARRAY, FIELD)                                      \
{                                                                          \
  double TmpSort[][2];                                                     \
                                                                           \
  for (int x =::ArrayResize(TmpSort, ::ArraySize(ARRAY)) - 1; x >= 0; x--) \
  {                                                                        \
    TmpSort[x][0] = (double)ARRAY[x].FIELD;                                \
    TmpSort[x][1] = x;                                                     \
  }                                                                        \
                                                                           \
  ::ArraySort(TmpSort);                                                    \
  ::ArrayReindex(ARRAY, TmpSort);                                          \
}                                  


Funziona senza problemi in MT 5, ma in MT 4 si lamenta diArraySwap perché Mql 4 non lo supporta...


Forse qualcuno ha qualche variante di strutture di array di ordinamento universali che funzionano in MT 5 e MT 4?


Posso ancora offrire una ricompensa per l'implementazione più veloce di 10$

Документация по MQL5: Операции с массивами / ArraySort
Документация по MQL5: Операции с массивами / ArraySort
  • www.mql5.com
//| Получение значений границ для тиковых объемов                    | //| Custom indicator initialization function                         | //| Custom indicator iteration function                              | //
 

Dovete scrivere la vostra struttura come una classe che eredita da CObject e scrivere il vostro metodo Compare, quindi usare CArrayObj. Questa sarà l'opzione più veloce.

E riguardo ArraySwap qui - https://www.mql5.com/ru/docs/array/arrayswap non dovrebbe essere difficile scrivere tale funzione per MT4.

 
Dmitry Fedoseev:

Dovete scrivere la vostra struttura come una classe che eredita da CObject e scrivere il vostro metodo Compare, quindi usare CArrayObj. Questa sarà l'opzione più veloce.

E riguardo ArraySwap qui - https://www.mql5.com/ru/docs/array/arrayswap non dovrebbe essere difficile scrivere tale funzione per MT4.

Ho letto queste informazioni.

Stiamo parlando di un array di strutture, non di un semplice array.

 
Vladimir Pastushak:

Ho letto queste informazioni.

Stiamo parlando di un array di strutture, non di un semplice array.

CArrayObj è un semplice array?

 
Dmitry Fedoseev:

CArrayObj è un semplice array?

No, non ho una relazione amichevole con OOP.

 

La variante di @fxsaber sarà la più veloce, perché il compilatore distribuirà le macro al codice completo

Per evitare la duplicazione del codice, avvolgete gli ordinamenti necessari per i campi richiesti nelle funzioni e usate


le varianti con ereditarietà daCObject saranno molto più lente, dovrete aggiungere i corrispondenti metodi Compare

 
Igor Makanu:

La variante di @fxsaber sarà la più veloce, perché il compilatore distribuirà le macro al codice completo

Per evitare la duplicazione del codice, avvolgete gli ordinamenti necessari per i campi richiesti nelle funzioni e usate


e le varianti con ereditarietàCObject saranno molto più lente, inoltre dovrete aggiungere i corrispondenti metodi Compare

Lì copiamo i dati da un array all'altro e poi mischiamo gli indici. Forse sarà più veloce usando ArraySort().

 

Ed ecco un'opzione: modificare la funzione per adattarla alla vostra struttura:

#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

struct SMy{
   int x1;
   int x2;
};

SMy s[3]={{4,44},{2,22},{3,33}};

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(){
   
   SortHoareUp(s);
   
   for(int i=0;i<3;i++){
      Alert(s[i].x1," ",s[i].x2);
   }
   
}


void SortHoareUp(SMy  &aAr[])
  {
   HoareUp(aAr,0,ArraySize(aAr)-1);
  }

void HoareUp(SMy  &aAr[],int aLeft,int aRight)
  {
   SMy tmp;
   int i=aLeft;
   int j=aRight;
   
   int xx=aAr[(aLeft+aRight)/2].x1; // int заменить на тип поля по которому выполняется сравнение
   
   do
     {
   while(i<aRight && aAr[i].x1<xx)i++;
   while(j>aLeft && xx<aAr[j].x1)j--;
   if(i<=j)
     {
      tmp=aAr[i];
      aAr[i]=aAr[j];
      aAr[j]=tmp;
      i++;
      j--;
     }
  }
   while(i<=j);
   if(aLeft<j)HoareUp(aAr,aLeft,j);
   if(i<aRight)HoareUp(aAr,i,aRight);
}
 

Ma con CObjArray

#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <Arrays/ArrayObj.mqh>

class CMyClass:public CObject{
   public:
      int x1;
      int x2;
      int x3;     
      CMyClass(int ax1,int ax2,int ax3){
         x1=ax1;
         x2=ax2;         
         x3=ax3;           
      }
      int Compare(const CObject *node,const int mode=0)const{
         const CMyClass * t=node;
         if(mode==0 && t.x1>this.x1){
            return(1);
         }
         if(mode==1 && t.x1<this.x1){
            return(1);         
         }
         return(-1);
      }      
};

CMyClass * tmp;
CArrayObj a;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(){

   a.Add(new CMyClass(1,11,111));
   a.Add(new CMyClass(2,22,222));   
   a.Add(new CMyClass(3,33,333));   
   
   Alert("===");
   
   Al(1);
   a.Sort(0);   
   Al(2);
   a.Sort(1);      
   Al(3);

   
  }
//+------------------------------------------------------------------+

void Al(int n){
   Alert("-"+(string)n+"-");
   for(int i=0;i<a.Total();i++){
      tmp=a.At(i);
      Alert(tmp.x1," ",tmp.x2," ",tmp.x3);
   }   
}
 
Dmitry Fedoseev:

Ma questa variante - per cambiare la funzione per adattarla alla vostra struttura:

non è affatto un'opzione - questa è una soluzione comune a un problema particolare, la portabilità di tali soluzioni per un uso successivo sarà commisurata alla scrittura da zero )))

Il codice nel primo post è implementato copiando, se il compito è quello di eseguire l'ordinamento in 2 o 3 posti

oppure, come ho suggerito sopra, se avete intenzione di usare l'ordinamento per campi diversi in diverse sezioni di codice, sarebbe meglio creare funzioni wrapper per le macro suggerite


HH: I sorgenti di C# con tutte le classi base sul sito Microsoft, ci sono dei tipi, e sono simili alle interfacce in SB, ma ahimè, non hanno finalizzato SB - hanno detto fai da te ;)

 
Igor Makanu:

non è affatto un'opzione - questa è una soluzione comune a un problema particolare, la portabilità di tali soluzioni per un uso successivo sarà paragonabile a scrivere da zero )))

Il codice nel primo post può essere implementato copiando se il compito è quello di eseguire l'ordinamento in 2 o 3 frammenti di codice

oppure, come ho suggerito sopra, se avete intenzione di usare l'ordinamento per campi diversi in diverse sezioni di codice, sarebbe meglio creare funzioni wrapper per le macro suggerite


HH: I sorgenti di C# con tutte le classi di base sul sito Microsoft, ci sono dei tipi, e sono simili alle interfacce in SB, ma ahimè, non hanno finalizzato SB - hanno detto fai da te ;)

Cambia il tipo di variabile in un posto e il compilatore mostrerà errori negli altri tre - cambia il nome del campo. Si potrebbe pensare che decine di strutture debbano essere ordinate da qualche parte. Sì, molto probabilmente una struttura richiede l'ordinamento.