Fonction - Méthode pour trier un tableau de structures. Prix 10$. - page 2

 
Dmitry Fedoseev:

Changez le type de variable à un endroit et le compilateur affichera des erreurs dans les trois autres - changez le nom du champ. On pourrait penser qu'il y a des dizaines de structures qui doivent être triées. Oui, une structure nécessite très probablement un tri.

Non, ne définissez pas la tâche de cette façon

définissez la tâche suivante : utilisez votre exemple pour trier la structure qui comporte des dizaines de champs par chaque champ

qu'il s'agisse d'une structure contenant toutes les propriétés de l'ordre "quatre" (OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....) - il y en a une douzaine

Et reproduisez le tri d'un tableau de telles structures par chaque champ avec vos exemples ? - imho, votre code va peser très lourd, et j'ai écrit plus haut qu'il ne sera pas possible d'utiliser ce code de manière répétée

 
Igor Makanu:

Non, ce n'est pas comme ça que vous devez définir la tâche.

définissez la tâche suivante : en utilisant votre exemple, triez la structure qui a des dizaines de champs par chaque champ

qu'il s'agisse d'une structure contenant toutes les propriétés de l'ordre "quatre" (OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....) - il y en a une douzaine

Et reproduisez le tri d'un tableau de telles structures par chaque champ avec vos exemples ? - imho, votre code va peser assez lourd. j'ai écrit plus haut qu'il ne sera pas possible d'utiliser ce code à plusieurs reprises.

Un problème issu du domaine de la science-fiction, jamais rencontré dans la pratique.

Vous pouvez créer un champ distinct pour le tri et, avant de procéder au tri, copier dans ce champ le contenu du champ sur lequel vous souhaitez effectuer le tri.

 
Vladimir Pastushak:

Dans MT 5 cela fonctionne sans problèmes dans MT 4 il blâmeArraySwap parce que Mql 4 ne le supporte pas....

#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:

Un défi du domaine de la fiction.

Non, il est possible d'utiliser MQL, tout comme vous avez suggéré d'utiliser SB

Mais le problème sera que ce code sera écrit pour une certaine tâche

Si nous donnons un exemple - le panneau du terminal avec les ordres a été reproduit comme une fenêtre dans MQL, le tri a été fait, tout tourne, tout fonctionne

Et si vous voulez utiliser une partie du code pour afficher le panneau "optimisation" du testeur, vous aurez une cargaison de changements. Il est plus facile d'écrire le code à partir de zéro, y compris les tris, et vous voudrez avoir des noms de champs lisibles par l'homme ? - sinon, il faut être l'auteur d'un "noyau" bien connu pour avoir en tête tous les noms d'identifiants sous la forme Abyrwalg (A Dog's Heart)

)))

 
Igor Makanu:

Non, il est possible d'utiliser MQL, tout comme vous avez suggéré d'utiliser SB

mais le problème sera que ce code sera écrit pour une tâche spécifique

Si nous donnons un exemple, le panneau du terminal avec les commandes a été reproduit comme une fenêtre dans MQL, le tri a été fait, tout tourne, tout fonctionne...

Et si vous voulez utiliser une partie du code pour afficher le panneau "optimisation" du testeur, vous obtiendrez une cargaison de modifications. Il est plus facile d'écrire le code à partir de zéro, y compris les tris, et vous voudrez avoir des noms de champs lisibles par l'homme ? - sinon, il faut être l'auteur d'un "noyau" bien connu pour avoir en tête tous les noms d'identifiants sous la forme Abyrwalg (A Dog's Heart)

)))

Tout ce qui peut être mal compris sera mal compris. Je ne parlais pas de la possibilité/impossibilité, mais de la nécessité pratique, c'est-à-dire de l'occurrence de cette tâche.

Ce n'est pas mon idée que pour chaque structure je doive écrire mon propre Compare().

 

Pourquoi trier le tableau/vecteur de structures épaisses dans différents champs ?

laissez-le tel qu'il est, il a le droit d'être encore plus constant :-) et pour des raisons différentes, vous pouvez construire des index.

/// код не проверял - написал "с руки", демонстрировать идею
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:

Ce n'est pas mon idée d'écrire un Compare() différent pour chaque structure.

C'est exactement comme ça, ou plutôt je ne connais pas d'autre moyen, et cette méthode sera liée à une tâche spécifique

et l'auteur veut une solution universelle pour 10 livres, eh bien, attendons de voir si quelque chose s'éclaircit

 
Maxim Kuznetsov:

Pourquoi trier le tableau/vecteur de structures épaisses dans différents champs ?

Laissez-le tel qu'il est, il a le droit de l'être encore plus :-) et pour des raisons différentes, vous pouvez construire des index.

Quelqu'un va écrire maintenant ... que c'est si gênant pour moi ... que nous ne sommes pas des femmes au foyer, mais des super-développeurs, et que nous devons utiliser toutes les possibilités des technologies de programmation modernes, alors qu'un tableau supplémentaire est quelque chose comme le Moyen Âge ...

Bien que, personnellement, je préfère cette option.

#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:

Pas du tout :
1) Il suffit d'insérer ArrayCopy dans la compilation conditionnelle, pas ArraySwap.
2) ArrayCopy doit être écrit dans une version personnalisée, car la version standard ne supporte pas les structures NonPod.
3) Nous avons besoin d'une compilation conditionnelle supplémentaire pour le tableau multi-domaine ArrayResize (la fonction donne des résultats différents pour les différentes versions de 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:

Ça n'arrivera pas :

La réponse n'était pas pour toutes les occasions. La plupart des gens ferment.