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

 
Dmitry Fedoseev :

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

아니, 작업을 잘못 넣어

다음 작업을 설정합니다. 예제를 사용하여 각 필드에 대해 수십 개의 필드가 있는 구조를 정렬합니다.

음, 그리고 구체적인 예 - "4" 주문(OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....)의 모든 속성을 포함하는 구조가 있다고 가정합니다. - 약 12개가 있을 것입니다.

각 필드에 대해 그러한 구조의 배열을 정렬하여 귀하의 예와 함께 재현하시겠습니까? - IMHO, 귀하의 코드는 꽤 적절할 것입니다. 그러한 코드를 재사용할 수 없다는 사실에 대해 위에서 썼습니다.

 
Igor Makanu :

아니, 작업을 잘못 넣어

다음 작업을 설정합니다. 예제를 사용하여 각 필드에 대해 수십 개의 필드가 있는 구조를 정렬합니다.

음, 그리고 구체적인 예 - "4" 주문(OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....)의 모든 속성을 포함하는 구조가 있다고 가정합니다. - 약 12개가 있을 것입니다.

각 필드에 대해 그러한 구조의 배열을 정렬하여 귀하의 예와 함께 재현하시겠습니까? - IMHO, 귀하의 코드는 꽤 적절할 것입니다. 그러한 코드를 재사용할 수 없다는 사실에 대해 위에서 썼습니다.

현실에서는 한 번도 접하지 못한 환상의 영역에서의 과제.

정렬 기준 필드를 별도로 만들 수 있으며 정렬하기 전에 정렬 기준 필드에서 복사합니다.

 
Vladimir Pastushak :

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

 #ifndef __MQL5__
   template < typename T>
   void ArraySwap ( T &Array1[], T &Array2[] )
  {
    T ArrayTmp[];

     ArrayCopy (ArrayTmp, Array1);
     ArrayFree (Array1);

     ArrayCopy (Array1, Array2);

     ArrayFree (Array2);
     ArrayCopy (Array2, ArrayTmp);

     return ;
  }
#endif // __MQL5__
 
Dmitry Fedoseev :

환상의 영역에서 온 작업.

예 아니요, 아마도 MQL을 통해 제안하신 대로 SB를 사용합니다.

그러나 문제는 이 코드가 특정 작업을 위해 작성된다는 것입니다.

글쎄, 예에서 - 그들이 MQL 창 형태의 주문으로 터미널 패널을 재생산하고 정렬을 수행했다면 모든 것이 회전하고 모든 것이 작동합니다

하지만 코드의 일부를 사용하여 "최적화" 테스터 패널을 재생하고 싶고 트롤리로 왜건을 편집할 수 있습니다. 기본적으로 처음부터 정렬을 포함하여 코드를 작성하는 것이 더 쉽습니다. 읽을 수 있는 형식의 구조 필드 이름? - 그렇지 않으면 Abyrvalg(Dog's Heart) 형식의 식별자 이름을 모두 기억하기 위해 잘 알려진 "core"의 작성자여야 합니다.

)))

 
Igor Makanu :

예 아니요, 아마도 MQL을 통해 제안하신 대로 SB를 사용합니다.

그러나 문제는 이 코드가 특정 작업을 위해 작성된다는 것입니다.

글쎄, 예에서 - 그들이 MQL 창 형태의 주문으로 터미널 패널을 재생산하고 정렬을 수행했다면 모든 것이 회전하고 모든 것이 작동합니다

하지만 코드의 일부를 사용하여 "최적화" 테스터 패널을 재생하고 싶고 트롤리로 자동차를 편집할 수 있습니다. 기본적으로 처음부터 정렬을 포함하여 코드를 작성하는 것이 더 쉽습니다. 읽을 수 있는 형식의 구조 필드 이름? - 그렇지 않으면 Abyrvalg(Dog's Heart) 형식의 식별자 이름을 모두 기억하기 위해 잘 알려진 "core"의 작성자여야 합니다.

)))

오해할 수 있는 것은 무엇이든 오해할 수 있습니다. 그는 가능성/불가능이 아니라 이에 대한 실질적인 필요성, 즉 이 과업의 발생을 염두에 두었습니다.

나는 각 구조에 대해 자신의 Compare()를 작성해야 한다는 생각을 하지 않았습니다.

 

다른 필드에서 두꺼운 구조 의 배열/벡터를 정렬하려면 어떻게 해야 합니까?

그대로 두십시오. 심지어 const :-)에 대한 권리가 있으며 다른 목적으로 인덱스를 작성할 수 있습니다.

 /// код не проверял - написал "с руки", демонстрировать идею
template < typename T>
int
ArrayIndexate( const T &arr[], int &index[], int (*compare)( const T&, const T&))
{
   /// инициализуем индексный массив
   int size= ArraySize (arr);
   if (size==- 1 || ArrayResize (index,size)==- 1 ) {
       return - 1 ;
   }
   for ( int i= 0 ;i<size;i++)
      index[i]=i;
   /// "пузырёк" - замените более быстрым методом
   for ( int i= 0 ;i<size;i++) {
       for ( int j=i+ 1 ;j<size;j++) {
         if ( compare(arr[index[i]],arr[index[j]] ) > 0 ) {
             int swap=index[i];
            index[i]=index[j];
            index[j]=swap;
         }
      }
   }
   // в массиве index[] теперь лежат индексы элементов arr[]
   return size;   
}
 
Dmitry Fedoseev :

나는 각 구조에 대해 자신의 Compare()를 작성해야 한다는 생각을 하지 않았습니다.

이것이 바로 그것이다, 아니면 오히려 나는 다른 방법을 모르겠고 이 방법은 특정 작업에 묶일 것이다

그리고 topikstarter는 10달러에 대한 보편적인 솔루션을 원합니다. 음, 잠시만 기다리면 갑자기 뭔가 명확해질 것입니다.

 
Maxim Kuznetsov :

다른 필드에서 두꺼운 구조 의 배열/벡터를 정렬하려면 어떻게 해야 합니까?

그대로 두십시오. 심지어 const :-)에 대한 권리가 있으며 다른 목적으로 인덱스를 작성할 수 있습니다.

이제 누군가가 쓸 것입니다... 나는 너무 불편합니다... 우리는 주부가 아니라 슈퍼 개발자이고 현대 프로그래밍 기술의 모든 가능성을 사용해야 하며 추가 배열은 일종의 중세 시대입니다...

개인적으로 나는 이 옵션을 더 좋아하지만.

 #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 }};
double sa[][ 2 ];

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart (){
   int size= ArraySize (s);
   ArrayResize (sa,size);
   for ( int i= 0 ;i<size;i++){
      sa[i][ 0 ]=s[i].x1; // поле по которому сортировать
      sa[i][ 1 ]=i;
   }
   ArraySort (sa);
   
   Alert ( "===" );
   for ( int i= 0 ;i<size;i++){
       int ii=( int )sa[i][ 1 ];
       Alert (s[ii].x1, " " ,s[ii].x2);
   }
   
}

 
fxsaber :

그것은 가지 않을거야 :
1) ArraySwap이 아닌 조건부 컴파일에 ArrayCopy를 삽입하면 됩니다.
2) 표준 ArrayCopy는 NonPod 구조를 지원하지 않으므로 ArrayCopy는 사용자 정의해야 합니다.
3) ArrayResize 다중 도메인 배열에 대한 조건부 컴파일이 한 번 더 필요합니다(함수는 MT 버전에 따라 다른 결과를 제공함)

 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);                                          \
}  
 
Sergey Dzyublik :

그것은 가지 않을거야 :

모든 경우에 답이 있는 것은 아닙니다. 대부분 문을 닫습니다.