mql5言語の特徴、微妙なニュアンスとテクニック - ページ 47

 
ミコラ_2 さん

このような?

https://www.mql5.com/ru/code/9336

構造体の配列と構造体フィールドによるソートについての質問でした。

 
アルチョム・トリシキン

構造体の配列を、構造体の任意の(文字列でない)フィールドで、リソース効率よくソート した人はいますか?

int, datetime, doubleの3つのフィールドを持つ構造体があり、この構造体からなるデータで満たされた配列があるとする。配列の各セルには、構造体のフィールドが入力される。

この配列をこれらのフィールドのいずれかでソートするにはどうしたらよいでしょうか。

配列 double[][2] を作成し、{ fieldvalue, arrayindex } と入力します。通常のArraySortでソートする(最初の変化で)。そして、インデックスに従って配列の中の構造体を並べるのです。これがMQLで考えられるすべての方法の中で、最も速い方法だと思います。
 
アレクセイ・ナヴォイコフ
配列 double[][2] を作成し、{ fieldvalue, arrayindex } のように記入する。標準的なArraySortでソートします(最初の変化で)。そして、インデックスに従って配列内の構造体を並べる必要があります。
この方法を回避したかったのです。他にも方法があるんじゃないかと思ったんです。
 
アルチョム・トリシキン
この方法を回避したかったのです。他にも方法があるんじゃないかと思ったんです。

なぜ迂回するのか?ソートはネイティブ関数で行われるため、手っ取り早い方法はありません。

 
アレクセイ・ナヴォイコフ

なぜ迂回するのか?ソートを行うのはネイティブの関数なので、もっと早く思いつくことはないでしょう。

実は、すぐに始めたんです。私は、誰かが構造体の配列を任意のフィールドでソートする 素晴らしい方法を発明しているのではないかと思いました。
 
アルチョム・トリシキン

構造体の配列を、構造体の任意の(文字列でない)フィールドで、リソース効率よくソート した人はいますか?

int, datetime, doubleの3つのフィールドを持つ構造体があり、この構造体からなるデータで満たされた配列があるとする。配列の各セルには、構造体のフィールドが入力される。

この配列をこれらのフィールドのいずれかでソートするにはどうしたらよいでしょうか。

こんにちは、複雑なデータ型の配列をソートできるような万能なソート関数が必要かというと、それは原理的に不可能です。

もし、既知の型の多要素ソート機能が必要なら、クラスを使って行うことができ、特にCArrayObjはそのために設計されています。

C#のような大人向けの言語でも、複雑なオブジェクトのソートはカスタムIComparerで解決していることを付け加えておく。すなわち、ソート基準をすべて自分で書かなければならない。

 
アルチョム・トリシキン
これは私が迂回したかった方法です。他にも方法があるのではと思ったのです。

方法は2つあります。

第一の方法は、演算子<

2つ目は、ファンクショナルなものです。

 

方法その1。

template <typename t>
void Sort(t& a[], bool ascending = true)
{
  if (ascending) SortShellUp(a);
  else           SortShellDn(a);
}

template <typename t>
void SortShellUp(t& a[])
{
  t tmp;
  int n[]={9,5,3,2,1};
  int i,j,k,g;
  int Len=ArraySize(a);
  for(k=0;k<5;k++)
  {
    g=n[k];
    for(i=g;i<Len;i++)
    {
      tmp=a[i];
      for(j=i-g;j>=0 && tmp<a[j];j-=g)
      {
        a[j+g]=a[j];
      }
      a[j+g]=tmp;
    }
  }
}

template <typename t>
void SortShellDn(t& a[])
{
  t tmp;
  int n[]={9,5,3,2,1};
  int i,j,k,g;
  int Len=ArraySize(a);
  for(k=0;k<5;k++)
  {
    g=n[k];
    for(i=g;i<Len;i++)
    {
      tmp=a[i];
      for(j=i-g;j>=0 && a[j]<tmp;j-=g)
      {
        a[j+g]=a[j];
      }
      a[j+g]=tmp;
    }
  }
}

struct DrawData
{
   float price;
   float percent;
   
   bool operator < (const DrawData& right) const
   {
      return price < right.price;
   }
};

{
   DrawData items[];
   // filling
   Sort(items);
}
 

2番目の方法は、オペレーターが完全に外部にいて、ソートに渡されるだけで、似ています。少し複雑ですが、はるかに汎用性があります。

必要ならアイデアを出しますが、それは後回しにしてください。

ソートはkodobaseをコピーペーストするだけで、高速化が必要な場合は自分でスマートなものを書く必要がありますが、一度書けばもう悩むことはないでしょう。
 
コンビナート です。

2番目の方法は、オペレーターが完全に外部にいて、ソートに渡されるだけで、似ています。少し複雑ですが、はるかに汎用性があります。


つまり - 関数への ポインタを 使用する必要があります。

理由: