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

 

大家好,有一个由fxsaber编写的函数

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


在MT 5中工作没有问题,但在MT 4中它抱怨ArraySwap,因为Mql 4不支持它...


也许有人有一些在MT 5和MT 4中工作的通用排序阵列 结构的变体?


我仍然可以为最快的执行者提供10美元的奖励。

Документация по MQL5: Операции с массивами / ArraySort
Документация по MQL5: Операции с массивами / ArraySort
  • www.mql5.com
//| Получение значений границ для тиковых объемов                    | //| Custom indicator initialization function                         | //| Custom indicator iteration function                              | //
 

你需要把你的结构写成一个继承自CObject的类,写出你的比较方法,然后使用CArrayObj。这将是最快的选择。

而关于ArraySwap这里--https://www.mql5.com/ru/docs/array/arrayswap,为MT4编写这样的函数应该不难。

 
Dmitry Fedoseev:

你需要把你的结构写成一个继承自CObject的类,写出你的比较方法,然后使用CArrayObj。这将是最快的选择。

而关于ArraySwap这里--https://www.mql5.com/ru/docs/array/arrayswap,为MT4编写这样的函数应该不难。

我读到了这些信息。

我们谈论的是一个结构数组,而不是一个简单的数组。

 
Vladimir Pastushak:

我已经读过这些信息。

我们谈论的是一个结构数组,而不是一个简单的数组。

CArrayObj 是一个简单的数组吗?

 
Dmitry Fedoseev:

CArrayObj是一个简单的数组吗?

不,我与OOP没有友好关系。

 

@fxsaber的 变体将是最快的,因为编译器将把宏部署到完整的代码中。

为了避免代码重复,将必要的排序按所需字段包装在函数中,并使用


继承自CObject 的变体会慢很多倍,你将不得不添加相应的比较方法

 
Igor Makanu:

@fxsaber的 变体将是最快的,因为编译器将把宏部署到完整的代码中。

为了避免代码重复,将必要的排序按所需字段包装在函数中,并使用


和具有CObject 继承性的变体将慢很多倍,此外你还必须添加相应的比较方法

在那里,我们将数据从一个数组复制到另一个数组,然后对索引进行洗牌。也许使用ArraySort()会更快。

 

而这里有一个选择--修改功能以适应你的结构。

#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}};

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(){
   
   SortHoareUp(s);
   
   for(int i=0;i<3;i++){
      Alert(s[i].x1," ",s[i].x2);
   }
   
}


void SortHoareUp(SMy  &aAr[])
  {
   HoareUp(aAr,0,ArraySize(aAr)-1);
  }

void HoareUp(SMy  &aAr[],int aLeft,int aRight)
  {
   SMy tmp;
   int i=aLeft;
   int j=aRight;
   
   int xx=aAr[(aLeft+aRight)/2].x1; // int заменить на тип поля по которому выполняется сравнение
   
   do
     {
   while(i<aRight && aAr[i].x1<xx)i++;
   while(j>aLeft && xx<aAr[j].x1)j--;
   if(i<=j)
     {
      tmp=aAr[i];
      aAr[i]=aAr[j];
      aAr[j]=tmp;
      i++;
      j--;
     }
  }
   while(i<=j);
   if(aLeft<j)HoareUp(aAr,aLeft,j);
   if(i<aRight)HoareUp(aAr,i,aRight);
}
 

但用CObjArray

#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <Arrays/ArrayObj.mqh>

class CMyClass:public CObject{
   public:
      int x1;
      int x2;
      int x3;     
      CMyClass(int ax1,int ax2,int ax3){
         x1=ax1;
         x2=ax2;         
         x3=ax3;           
      }
      int Compare(const CObject *node,const int mode=0)const{
         const CMyClass * t=node;
         if(mode==0 && t.x1>this.x1){
            return(1);
         }
         if(mode==1 && t.x1<this.x1){
            return(1);         
         }
         return(-1);
      }      
};

CMyClass * tmp;
CArrayObj a;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(){

   a.Add(new CMyClass(1,11,111));
   a.Add(new CMyClass(2,22,222));   
   a.Add(new CMyClass(3,33,333));   
   
   Alert("===");
   
   Al(1);
   a.Sort(0);   
   Al(2);
   a.Sort(1);      
   Al(3);

   
  }
//+------------------------------------------------------------------+

void Al(int n){
   Alert("-"+(string)n+"-");
   for(int i=0;i<a.Total();i++){
      tmp=a.At(i);
      Alert(tmp.x1," ",tmp.x2," ",tmp.x3);
   }   
}
 
Dmitry Fedoseev:

但这个变体--改变功能以适应你的结构。

根本不是一个选项--这是一个特定问题的通用解决方案,这种解决方案的可移植性在以后的使用中会与从头编写相称 ))

第一个帖子中的代码是通过复制实现的,如果任务是在2或3个地方进行排序

或者,正如我上面所建议的,如果你要在不同的代码部分使用不同字段的排序,最好为建议的宏创建包装函数


HH:微软网站上所有基类的C#来源,有多种,它们与SB中的接口类似,但可惜,他们没有最终确定SB--他们说自己做;)

 
Igor Makanu:

根本不是一个选项--这是一个特定问题的通用解决方案,这种解决方案的可移植性在以后的使用中将与从头开始编写相媲美 ))

如果任务是在2或3个代码片段中进行排序,第一个帖子中的代码可以通过复制来实现

或者,正如我上面所建议的,如果你要在不同的代码部分使用不同字段的排序,最好为建议的宏创建包装函数


HH:微软网站上的C#与所有基本类的来源,有各种各样的,它们与SB中的接口相似,但可惜的是,他们没有最终确定SB--他们说自己做;)

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

原因: