Função - Método para ordenar uma série de estruturas. Prêmio 10$

Vladimir Pastushak  

Olá a todos, há uma função escrita pela 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);                                          \
}                                  


Funciona sem problemas no MT 5, mas no MT 4 reclama doArraySwap porque o Mql 4 não o suporta...


Talvez alguém tenha algumas variantes de estruturas de ordenação universal trabalhando em MT 5 e MT 4 ?


Eu ainda posso oferecer uma recompensa pela implementação mais rápida de 10$

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

Você precisa escrever sua estrutura como uma classe que herda do CObject e escrever seu método de comparação, depois use CArrayObj. Esta será a opção mais rápida.

E sobre o ArraySwap aqui - https://www.mql5.com/ru/docs/array/arrayswap não deve ser difícil escrever tal função para o MT4.

Eu li esta informação.

Estamos falando de um conjunto de estruturas, não de um simples conjunto.

Dmitry Fedoseev  
Vladimir Pastushak:

Eu li esta informação.

Estamos falando de um conjunto de estruturas, não de um simples conjunto.

OCArrayObj é um simples conjunto?

Vladimir Pastushak  
Dmitry Fedoseev:

O CArrayObj é um simples conjunto?

Não, eu não tenho uma relação amigável com o OOP.

Igor Makanu  

A variante do @fxsaber será a mais rápida, porque o compilador implantará as macros no código completo

Para evitar duplicação de códigos, embrulhe as ordenações necessárias pelos campos obrigatórios nas funções e uso


As variantes com herança deCObject serão muitas vezes mais lentas, você terá que adicionar os métodos de comparação correspondentes

Dmitry Fedoseev  
Igor Makanu:

A variante do @fxsaber será a mais rápida, porque o compilador implantará as macros no código completo

Para evitar duplicação de códigos, embrulhe as ordenações necessárias pelos campos obrigatórios nas funções e uso


e as variantes com herançaCObject serão muitas vezes mais lentas, além disso, você terá que adicionar os métodos de comparação correspondentes

Lá, copiamos os dados de uma matriz para outra e depois embaralhamos os índices. Talvez seja mais rápido usando o ArraySort().

Dmitry Fedoseev  

E aqui está uma opção - modificar a função para se adequar à sua estrutura:

#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);
}
Dmitry Fedoseev  

Mas com a 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);
   }   
}
Igor Makanu  
Dmitry Fedoseev:

Mas esta variante - mudar a função para se adequar à sua estrutura:

não é uma opção - esta é uma solução comum para um problema particular, a portabilidade de tais soluções para uso posterior será proporcional à escrita a partir do zero )))

O código no primeiro posto é implementado através de cópia, se a tarefa for realizar a triagem em 2 ou 3 lugares

ou, como sugeri acima, se você vai usar a classificação por diferentes campos em diferentes seções de código, seria melhor criar funções de invólucro para as macros sugeridas


HH: As fontes de C# com todas as classes base no site da Microsoft, existem tipos, e são semelhantes às interfaces no SB, mas infelizmente, eles não finalizaram o SB - eles disseram para fazer isso você mesmo ;)

Dmitry Fedoseev  
Igor Makanu:

não é uma opção - esta é uma solução comum para um problema particular, a portabilidade de tais soluções para uso posterior será comparável à escrita a partir do zero )))

O código no primeiro post pode ser implementado através de cópia se a tarefa for realizar a ordenação em 2 ou 3 fragmentos de código

ou, como sugeri acima, se você vai usar a classificação por diferentes campos em diferentes seções de código, seria melhor criar funções de invólucro para as macros sugeridas


HH: As fontes de C# com todas as classes básicas no site da Microsoft, existem tipos, e são semelhantes às interfaces no SB, mas infelizmente, eles não finalizaram o SB - eles disseram para fazer você mesmo ;)

Alterar o tipo de variável em um lugar e o compilador mostrará erros nos outros três - alterar o nome do campo. Você pensaria que dezenas de estruturas precisam ser classificadas em algum lugar. Sim, o mais provável é que uma estrutura exija uma classificação.

Razão: