기능 - 구조 배열을 정렬하는 방법입니다. 상금 10$

 

여러분, 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);                                          \
}                                  


MT 5에서는 MT 4에서 문제 없이 작동합니다. Mql 4가 지원하지 않기 때문에 ArraySwap 에서 맹세합니다...


5번과 4번 모두에서 작동 하는 일련의 구조를 보편적으로 정렬하는 옵션이 있는 사람이 있을까요?


나는 또한 $ 10의 가장 빠른 구현에 대한 보상을 제공 할 수 있습니다

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

구조를 CObject를 상속하는 클래스로 작성하고 자신의 비교 방법 Compare를 작성한 다음 CArrayObj를 사용해야 합니다 . 이것은 가장 빠른 옵션이 될 것입니다.

ArraySwap에 대한 정보는 여기 - https://www.mql5.com/ru/docs/array/arrayswap MT4용으로 이러한 기능을 작성하는 것은 어렵지 않아야 합니다.

 
Dmitry Fedoseev :

CObject를 상속하는 클래스로 구조체를 작성하고 자신의 Compare 메서드를 작성한 다음 CArrayObj를 사용해야 합니다. 이것은 가장 빠른 옵션이 될 것입니다.

ArraySwap에 대한 정보는 여기 - https://www.mql5.com/ru/docs/array/arrayswap MT4용으로 이러한 기능을 작성하는 것은 어렵지 않아야 합니다.

이 정보를 읽었습니다.

우리는 단순한 배열이 아니라 구조의 배열에 대해 이야기하고 있습니다.

 
Vladimir Pastushak :

이 정보를 읽었습니다.

우리는 단순한 배열이 아니라 구조의 배열에 대해 이야기하고 있습니다.

그리고 CArrayObj 는 단순한 배열입니까?

 
Dmitry Fedoseev :

그리고 CArrayObj는 단순한 배열입니까?

아니요, 저는 PLO와 우호적인 관계를 갖고 있지 않았습니다.

 

@fxsaber 의 버전이 가장 빠르기 때문에 컴파일러는 매크로 대체를 전체 코드로 확장합니다.

코드 중복이 없도록 함수의 필요한 필드별로 필요한 정렬을 래핑하고 사용


CObject 에서 상속된 옵션 은 몇 배나 느려지고 해당하는 비교 메서드를 지속적으로 추가해야 합니다.

 
Igor Makanu :

@fxsaber 의 버전이 가장 빠르기 때문에 컴파일러는 매크로 대체를 전체 코드로 확장합니다.

코드 중복이 없도록 함수의 필요한 필드별로 필요한 정렬을 래핑하고 사용


CObject 에서 상속된 옵션 은 몇 배나 느려지고 해당하는 비교 메서드를 지속적으로 추가해야 합니다.

거기에서 한 배열에서 다른 배열로 데이터를 복사한 다음 인덱스를 재정렬합니다. ArraySort()를 사용하면 더 빠를 수도 있습니다.

 

그러나 그러한 옵션은 구조에 맞게 기능을 변경하는 것입니다.

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

그러나 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 :

그러나 그러한 옵션은 구조에 맞게 기능을 변경하는 것입니다.

전혀 옵션이 아님 - 이것은 특정 문제에 대한 일반적인 솔루션이며, 이후 사용을 위한 이러한 솔루션의 이식성은 처음부터 작성하는 것과 비례합니다)))

작업이 코드의 2~3개 위치에서 정렬을 수행하는 경우 첫 번째 메시지의 코드를 복사하여 전송합니다.

또는 위에서 제안한 것처럼 코드의 다른 부분에서 구조의 다른 필드별로 정렬을 자주 사용할 것으로 예상되는 경우 제안된 매크로에 대한 래퍼 함수를 만드는 것이 좋습니다.


추신: Microsoft 웹 사이트의 모든 기본 클래스가 있는 C# 소스, 정렬이 있으며 SB의 인터페이스처럼 보이지만 안타깝게도 SB를 완료하지 않았습니다. 직접 하라고 했습니다.)

 
Igor Makanu :

전혀 옵션이 아님 - 이것은 특정 문제에 대한 일반적인 솔루션이며, 이후 사용을 위한 이러한 솔루션의 이식성은 처음부터 작성하는 것과 비례합니다)))

작업이 코드의 2~3개 위치에서 정렬을 수행하는 경우 첫 번째 메시지의 코드를 복사하여 전송합니다.

또는 위에서 제안한 것처럼 코드의 다른 부분에서 구조의 다른 필드별로 정렬을 자주 사용할 것으로 예상되는 경우 제안된 매크로에 대한 래퍼 함수를 만드는 것이 좋습니다.


추신: Microsoft 웹 사이트의 모든 기본 클래스가 있는 C# 소스, 정렬이 있으며 SB의 인터페이스처럼 보이지만 안타깝게도 SB를 완료하지 않았습니다. 직접 하라고 했습니다.)

한 곳에서 변수의 유형을 변경하면 컴파일러는 다른 세 곳에서 오류를 표시합니다. 즉, 필드 이름을 변경하십시오. 수십 개의 구조가 정렬을 요구한다고 생각할 수 있습니다. 예, 하나의 구조가 정렬을 요구할 가능성이 높습니다.