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

 
Dmitry Fedoseev:

一か所で変数の型を変更すると、コンパイラは他の3か所でエラーを表示します - フィールド名を変更します。仕分けが必要な構造が何十個もあると思うでしょう。そうですね、1つの構造で仕分けが必要な場合がほとんどです。

いいえ、このようにタスクを設定しないでください

次のタスクを設定します:あなたの例を使用して、数十のフィールドを持つ構造を各フィールドでソートします。

注文"4 "のすべてのプロパティ(OrderStoploss(), OrderTakeProfit(), OrderOpenTime()...)を含む構造体とする。- 十数人いる

また、そのような構造体の配列を各フィールドでソートすることを、あなたの例で再現してください。- imho、あなたのコードはかなり重くなり、私はこのコードを再利用することは不可能であることを上に書きました。

 
Igor Makanu:

いや、それはタスクの設定方法ではない。

次のタスクを設定する:あなたの例を使用して、数十のフィールドを持つ構造を各フィールドでソートします。

注文"4 "のすべてのプロパティ(OrderStoploss(), OrderTakeProfit(), OrderOpenTime()...)を含む構造体であることとする。- 十数人いる

また、そのような構造体の配列を各フィールドでソートすることを、あなたの例で再現してください。- このコードを繰り返し使用することは不可能であると、上に書きました。

SFの世界の問題で、実際には決して遭遇しない。

ソートするフィールドを別に作り、ソートする前に、ソートしたいフィールドからそのフィールドにコピーすることができます。

 
Vladimir Pastushak:

MT5では問題なく動作するのですが、MT4ではMql4がサポートしていないため、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のウィンドウとして再現され、ソートが行われ、すべてが回転し、すべてが機能する場合について説明します。

また、テスターの「最適化」パネルを表示するためにコードの一部を使いたい場合、車一台分の変更が発生します。 ソートも含めて一からコードを書く方が簡単ですし、人間が読めるフィールド名を用意したくなるのではないでしょうか?- でなければ、よく知られた「カーネル」の作者でなければ、Abyrwalgh(犬の心臓)のような形の識別子の名前をすべて覚えておくことはできません。

)))

 
Igor Makanu:

いいえ、MQLを使用することは可能です、あなたがSBを使用することを提案したように

しかし、問題は、このコードが特定のタスクのために書かれたものであることです。

例えるなら、注文のあるターミナルパネルがMQLのウィンドウとして再現され、ソートが行われ、すべてが回転し、すべてが動作している状態です

また、テスターの「最適化」パネルを表示するためにコードの一部を使いたい場合、車一台分の変更が発生します。 ソートも含めて一からコードを書く方が簡単ですし、人間が読めるフィールド名を用意したくなるのではないでしょうか?- でなければ、有名な「カーネル」の作者でなければ、Abyrwalg(犬の心臓)の形の識別子の名前をすべて覚えておくことはできないでしょう。

)))

誤解されるものは誤解される。可能性・不可能性ではなく、現実的な必要性、つまりこのタスクの発生を意味しました。

構造体ごとにCompare()を書かなければならないというのは、私の考えではないですね。

 

厚い構造体の配列/ベクトルを 異なるフィールドにソート する理由は?

このままにしておくと、さらに制約を受けることになります :-) また、さまざまな目的でインデックスを構築することができます。

/// код не проверял - написал "с руки", демонстрировать идею
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() を書くのは、私のアイデアではありません。

まさにその通り、というかそれ以外の方法を知らないので、この方法は特定のタスクに縛られることになります

で、著者は10ポンドで普遍的な解決策を望んでいる。まあ、何かがクリアになるのを待とうじゃないか。

 
Maxim Kuznetsov:

厚い構造体の配列/ベクトルを 異なるフィールドにソート する理由は?

そのままにしておくと、さらに制約を受ける権利があります :-) また、さまざまな目的のためにインデックスを構築することができます。

誰かが今書くだろう...それは私にとってとても不便だ...我々は主婦ではなく、スーパー開発者であり、我々は追加の配列は、中世のようなものですが、現代のプログラミング技術のすべての可能性を使用する必要があります...その

でも、個人的にはこの選択肢の方が好きですね。

#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構造に対応していないため、カスタムで記述する必要があります。
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:

それはないでしょう。

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