Función - Método para ordenar una matriz de estructuras. Premio 10$ - página 8

 
Georgiy Merts:

Personalmente, escribí yo mismo hace mucho tiempo una clase CStructWrapper, heredada de CObject (CMyObject es en realidad lo mismo, con campos de depuración adicionales), y para la ordenación uso una función estándar.

Si necesito un array de estructuras, declaro una clase derivada basada en esta plantilla. En él, declaro una función para comparar los campos necesarios de la estructura. Y luego - uso una clase estándar de un array de objetos con ordenación.

Los objetos creados pueden copiarse directamente desde las estructuras utilizando el operador de asignación. Si es necesario, los copio.

Desgraciadamente, no tengo tanta experiencia en POO como para poder entender tu código.

 
Vladimir Pastushak:

Desgraciadamente, todavía no soy lo suficientemente fuerte en OOP para entender su código.

Es sólo una clase que contiene nuestra estructura en su interior.

Y todo tipo de operadores de copia, permitiendo utilizar el signo de asignación (=) directamente entre el objeto y la estructura.

Cuando necesito un array de estructuras - creo un array de dichos objetos. Cada uno tiene la estructura requerida. Además, en esta clase se define una función de comparación, necesaria para ordenar y buscar. Todo, entonces se utilizan las funciones estándar de la clase CArrayObj

 
Vladimir Pastushak:

Desgraciadamente, aún no soy lo suficientemente fuerte en OOP para entender su código.

Pues bien, implementa el método sin OOP. No te preocupes, puedes tomar el método "quick sorting" de SB(hay muchos algoritmos de ordenación, alguien subió un video como visualización de diferentes algoritmos, todos son mejores en alguna situación, pero este es el óptimo y el más usado) y cambiarlo para tu estructura, aquí debes elegir, por qué campo de la estructura vas a comparar más vs menos. aproximadamente así (digamos, por alguna cadenatu_valor)

//+------------------------------------------------------------------+
//| Method QuickSort                                                 |
//+------------------------------------------------------------------+
void CArrayString::QuickSort(int beg,int end,const int mode)
  {
   int    i,j;
   string p_string;
   string  YOUR_STRUCT t_string;
//--- check
   if(beg<0 || end<0)
      return;
//--- sort
   i=beg;
   j=end;
   while(i<end)
     {
      //--- ">>1" is quick division by 2
      p_string=m_data[(beg+end)>>1].your_value;
      while(i<j)
        {
         while(m_data[i].your_value<p_string)
           {
            //--- control the output of the array bounds
            if(i==m_data_total-1)
               break;
            i++;
           }
         while(m_data[j].your_value>p_string)
           {
            //--- control the output of the array bounds
            if(j==0)
               break;
            j--;
           }
         if(i<=j)
           {
            t_string=m_data[i];
            m_data[i++]=m_data[j];
            m_data[j]=t_string;
            //--- control the output of the array bounds
            if(j==0)
               break;
            j--;
           }
        }
      if(beg<j)
         QuickSort(beg,j);
      beg=i;
      j=end;
     }
  }
 
Vladimir Pastushak:

Desgraciadamente, aún no soy lo suficientemente fuerte en OOP para entender su código.

¿Pero al menos eres bueno para distinguir *** de ***?

 
Vladimir Pastushak:

Lamentablemente, ahora incluso los métodos que fxsaber sugirió ya no funcionan.

Y estoy buscando métodos para ordenar un array de estructuras. ¿Alguien tiene alguna variante que funcione?

Creo que esa solución a la limitación del idioma funcionaría.

#property strict

// Сортировка массива структур и указателей на объекты по (под-) полю/методу.
#define  ArraySortStruct(T, ARRAY, FIELD)                                         \
{                                                                                \
  class SORT                                                                     \
  {                                                                              \
  private:                                                                       \
    static void Swap( T &Array[], const int i, const int j )                     \
    {                                                                            \
      const T Temp = Array[i];                                                   \
                                                                                 \
      Array[i] = Array[j];                                                       \
      Array[j] = Temp;                                                           \
                                                                                 \
      return;                                                                    \
    }                                                                            \
                                                                                 \
    static int Partition( T &Array[], const int Start, const int End )           \
    {                                                                            \
      int Marker = Start;                                                        \
                                                                                 \          
      for (int i = Start; i <= End; i++)                                         \
        if (Array[i].##FIELD <= Array[End].##FIELD)                              \
        {                                                                        \
          SORT::Swap(Array, i, Marker);                                          \
                                                                                 \
          Marker++;                                                              \
        }                                                                        \
                                                                                 \
       return(Marker - 1);                                                       \
    }                                                                            \
                                                                                 \
    static void QuickSort( T &Array[], const int Start, const int End )          \
    {                                                                            \
      if (Start < End)                                                           \
      {                                                                          \
        const int Pivot = Partition(Array, Start, End);                          \
                                                                                 \
        SORT::QuickSort(Array, Start, Pivot - 1);                                \
        SORT::QuickSort(Array, Pivot + 1, End);                                  \
      }                                                                          \
                                                                                 \
      return;                                                                    \
    }                                                                            \
                                                                                 \
  public:                                                                        \
    static void Sort( T &Array[], int Count = WHOLE_ARRAY, const int Start = 0 ) \
    {                                                                            \
      if (Count == WHOLE_ARRAY)                                                  \
        Count = ::ArraySize(Array);                                              \
                                                                                 \
      SORT::QuickSort(Array, Start, Start + Count - 1);                          \
                                                                                 \
      return;                                                                    \
    }                                                                            \
  };                                                                             \
                                                                                 \
  SORT::Sort(ARRAY);                                                             \
}

void OnStart()
{
  MqlRates Rates[];
  
  CopyRates(_Symbol, PERIOD_CURRENT, 0, 5, Rates); // Взяли бары
  
  Print("\nБары без сортировки - как получили.");
  ArrayPrint(Rates);
  
  Print("\nСортируем по open-цене.");
  ArraySortStruct(MqlRates, Rates, open);
  ArrayPrint(Rates);

  Print("\nСортируем по high-цене.");
  ArraySortStruct(MqlRates, Rates, high);
  ArrayPrint(Rates);

  Print("\nСортируем по времени.");
  ArraySortStruct(MqlRates, Rates, time);
  ArrayPrint(Rates);
}
 
Dmitry Fedoseev:

¿Pero al menos eres bueno para distinguir *** de ***?

Al igual que la gente... Creo que me has confundido con otra persona...

 
Vladimir Pastushak:

También la gente... Creo que me has confundido con otra persona...

Esa es la cuestión: creo que lo soy. Pero no lo soy.

 
Dmitry Fedoseev:

Esa es la cuestión, que "parece". Pero no estoy confundido.

¿A qué se debe esta "fricción"? ¿Qué tiene que ver con el tema?

 
Сергей Таболин:

¿Qué sentido tiene esta "fricción"? ¿Qué tiene esto que ver con el tema?

¿Por qué? ¿Hay un tema aparte para esto?

 
Aleksey Mavrin:

Pues bien, implementa el método sin OOP. No vayas demasiado lejos, toma el método de "clasificación rápida" de SB

fxsaber:

Creo que esta solución a la limitación del idioma será suficiente.

¡Gracias, amigos!

Lo tengo en mi agujero.