関数 - 構造体の配列をソートするためのメソッド。賞金10ドル - ページ 3

 
fxsaber:

答えは、どんな場面でも使えるというものではありませんでした。ほとんどが閉店しています。

fxsaber さん、どうもありがとうございました。10ドルの振込先

fxsaber
fxsaber
  • www.mql5.com
Опубликовал пост Пример математически правильной Торговой Системы Ниже математически правильная ТС с проверкой, что это так. Логика ТС следующая: переворачивается вовнутрь, когда цена с запасом пересекает EMA-шку от цены. // Пример математически правильной ТС с возможностью ее проверки в MT5-Тестере. // https://www.mql5... Добавил тему...
 
Maxim Kuznetsov:
mqlで直接非現実化可能。
 
Vladimir Pastushak:

fxsaber さん、どうもありがとうございました。10ドルの振込先

どういたしまして。

 
fxsaber:

どういたしまして。

ソートされた構造体の中に文字列データがあると、この方法はうまくいきません...。

 
Vladimir Pastushak:

ソートされた構造体に文字列データがあると、この方法はうまくいきません......。

これを使って ください。

Особенности языка mql5, тонкости и приёмы работы
Особенности языка mql5, тонкости и приёмы работы
  • 2019.04.19
  • www.mql5.com
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql5, примеры решения тех, или иных задач...
 
TheXpert:
mqlで直接実装できない。

ところで、そうなんです :-( 関数への (擬似) ポインタはワイルドカードにはなり得ないのです

しかし、何を偉そうに...と思うのが人情だ。

C/C++の後、このような振る舞いは、MQLで「網目を作る」試みから嫌気がさします。特定の個別ソリューションのみ

 
fxsaber:

これを使って ください。

これも使えない(((


ローカルクラスでのテンプレート宣言の禁止


 
Maxim Kuznetsov:

ところで、そうなんです :-( 関数への (擬似) ポインタはワイルドカードにはなりえません。

しかし、何を偉そうに...と思うのが人情だ。

C/C++の後、このような振る舞いは、MQLで「ネット性を作り出す」試みから私をうんざりさせる。特定の個別ソリューションのみ

何が問題なのか?
必要であれば、提案されたコードをそのまま使用することができます。

template <typename T, typename Func>
int
ArrayIndexate(const T &arr[],int &index[], Func compare)
{
   /// инициализуем индексный массив
   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;   
}

void OnStart(){ 
   NonPod arr_nonpod[9];
   ArrayInit(arr_nonpod);    
   PRINT(ArrayPrintValue(arr_nonpod));                      // 9 8 7 6 5 4 3 2 1 
   
   int index[];
   LAMBDA_CREATE_P2(int, compare, const NonPod &p1, const NonPod &p2, {
      return p1.value >= p2.value;
   });
   ArrayIndexate(arr_nonpod, index, LAMBDA_FUNC(compare));
   
   string result = "";
   for(int i = 0; i < ArraySize(index); ++i){
      result += string(arr_nonpod[index[i]].value) + " ";   
   }
   PRINT(result);                                           //1 2 3 4 5 6 7 8 9 
}
 
Vladimir Pastushak:

これも使えない(((

ローカルクラスでのテンプレート宣言の禁止

確認したところ、動作しています。

 
自分の作品を共有するのはあまり好きではないので、Podアレイの実行時の最適化をいくつかカットしています。
その代わり、機能を若干拡張。
- は、MT4(ビルド1262、ME2380)およびMT5(ビルド2380、ME2380)用にコンパイルされます。
- Pod構造、NonPod構造の両方をサポートします。
- は、構造体の静的配列と動的 配列を扱うことができます。

#property strict
#define  PRINT(x) ; Print(#x, ":", string(x))
#define  CONSTRAINT(ex) if(false){string test = typename(ex);}

//+------------------------------------------------------------------+
//| Test Inviroment                                                  |
//+------------------------------------------------------------------+
struct Pod{
   int value;
};

struct NonPod : public Pod{
   uchar data[];
};

template<typename T>
void ArrayInit(T &arr[]){
   int size = ArraySize(arr);
   for(int i = 0; i < size; ++i){
      arr[i].value = size - i;
   }
}

template<typename T>
string ArrayPrintValue(T &arr[]){
   string result = "";
   for(int i = 0; i < ArraySize(arr); ++i){
      result += string(arr[i].value) + " ";
   }
   return result;
}

//+------------------------------------------------------------------+
//| Fixed code                                                       |
//+------------------------------------------------------------------+
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)];
   }

#ifdef __MQL5__    
   if(!::ArraySwap(Array, TmpArray)){
      ArrayFunctions::ArrayCopy(Array, TmpArray);
   }
#endif 
#ifdef __MQL4__
   ArrayFunctions::ArrayCopy(Array, TmpArray);
#endif              
  return;     
}             

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

//+------------------------------------------------------------------+
//| Test                                                                 |
//+------------------------------------------------------------------+
void OnStart(){
   Pod arr_pod[9];
   NonPod arr_nonpod[];
   ArrayResize(arr_nonpod, 9);

   ArrayInit(arr_pod); 
   ArrayInit(arr_nonpod);
   
   PRINT(ArrayPrintValue(arr_pod));      // 9 8 7 6 5 4 3 2 1 
   PRINT(ArrayPrintValue(arr_nonpod));   // 9 8 7 6 5 4 3 2 1 
   
   ArraySortStruct(arr_pod, value);
   ArraySortStruct(arr_nonpod, value);
   
   
   PRINT(ArrayPrintValue(arr_pod));      // 1 2 3 4 5 6 7 8 9 
   PRINT(ArrayPrintValue(arr_nonpod));   // 1 2 3 4 5 6 7 8 9 
}

//+------------------------------------------------------------------+
//| Optimization Standat Array Functions                             |
//+------------------------------------------------------------------+
class ArrayFunctions{   
public:
//+------------------------------------------------------------------+
//| Copies an array into another one                                 |
//+------------------------------------------------------------------+
   template<typename T_dst, typename T_src>
   static int ArrayCopy(T_dst &dst_array[], const T_src &src_array[], int dst_start = 0, int src_start = 0, int count = WHOLE_ARRAY){
      CONSTRAINT(dst_array[0] = src_array[0]);
      if(dst_start < 0 || src_start < 0){
         return -1;
      }
      if(ArraySize(src_array) - src_start <= 0){
         return -1;
      }
      int max_count = MathMin(ArraySize(dst_array) - dst_start, ArraySize(src_array) - src_start);
      count = count > 0 ? count : max_count;
      count = count < max_count ? count : max_count;      
      
      int result = ArrayCopy_AnyType(dst_array, src_array, dst_start, src_start, count);
      return result;
   }
//+------------------------------------------------------------------+
private:  
   template<typename T_dst, typename T_src>
   static int ArrayCopy_AnyType(T_dst &dst_array[], const T_src &src_array[], int dst_start, int src_start, int count){
      int dst_size = dst_start + count;
      if(dst_size > ArraySize(dst_array)){
         ArrayResize(dst_array, dst_size);
      }
      if(dst_size >= src_start && dst_start <  src_start){
         for(int i = 0; i < count; ++i){
            dst_array[dst_start + i] = src_array[src_start + i];
         }
      }
      else{
         for(int i = count - 1; i >= 0; --i){
            dst_array[dst_start + i] = src_array[src_start + i];
         }
      }
      return count;     
   }
};