功能 - 对一个结构数组进行排序的方法。奖金10元 - 页 2

 
Dmitry Fedoseev:

在一个地方改变变量类型,编译器会在另外三个地方显示错误--改变字段名。你会认为有几十种结构需要整理。是的,一个结构很可能需要进行分类。

不,不要以这种方式设置任务

设置以下任务:使用你的例子,按每个字段对有几十个字段的结构进行排序

让它成为一个结构,包含订单"四 "的所有属性(OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....)。- 有十几个人

并用你的例子重现这种结构的数组按每个字段排序的情况?- 我认为,你的代码会很重,而且我在上面写到,不可能重复使用这个代码。

 
Igor Makanu:

不,这不是你应该设置的任务。

设定以下任务:使用你的例子,按每个字段对有几十个字段的结构进行排序

让它成为一个结构,包含订单"四 "的所有属性(OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....)- 有十几个人

并用你的例子重现这种结构的数组按每个字段排序的情况?- 我认为,你的代码将相当重。 我在上面写道,不可能重复使用这个代码。

这是一个来自科幻小说领域的问题,在实践中从未遇到过。

你可以做一个单独的字段来排序,在排序之前,从你想排序的字段中复制到它。

 
Vladimir Pastushak:

在MT 5中,它的工作没有问题,在MT 4中,它指责ArraySwap,因为Mql 4不支持它...。

#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的一个窗口,分类已经完成,一切都在旋转,一切都在工作。

而如果你想用一部分代码来显示测试器的 "优化 "面板,你会得到一车的改动。 从头开始写代码更容易,包括排序,你会希望有人类可读的字段名吗?- 否则,你需要成为一个知名的 "内核 "的作者,以记住所有以Abyrwalg(狗的心)形式出现的标识符的名称。

)))

 
Igor Makanu:

不,可以使用MQL,就像你建议的使用SB一样。

但问题是,这段代码是为一个特定的任务编写的。

如果我们举个例子,有订单的终端面板已经被复制成MQL的一个窗口,分类已经完成,一切都在旋转,一切都在工作。

而如果你想用一部分代码来显示测试器的 "优化 "面板,你会得到一车的改动。 从头开始写代码更容易,包括排序,你会希望有人类可读的字段名吗?- 否则,你需要成为一个著名的 "内核 "的作者,以记住所有的标识符的名字,以Abyrwalgh(一个狗的心脏)的形式。

)))

任何可能被误解的东西都会被误解。我指的不是可能性/不可能性,而是实际需要,即这项任务的发生。

这不是我的主意,你必须为每个结构写出自己的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()并不是我的主意。

这正是它的方式,或者说我不知道其他的方式,这个方法将与一个特定的任务相联系

而作者想用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)在条件编译中插入ArrayCopy就可以了,而不是ArraySwap。
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:

不会的。

答案是不适合所有场合。大多数人接近。