Скачать MetaTrader 5

Сортировка массивов

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
slba
82
slba  

Новичок.

Вопрос по MQL4: возможно ли сохранить индексы чисел исходного одномерного массива после его сортировки по возрастанию или убыванию ?
Необходимость в идентификации при выводе Print. (Значения некоторых чисел исходного массива могут быть одинаковыми).
Если возможно, прошу помочь примером.

Dmitry Fedoseev
44508
Dmitry Fedoseev  
сделать еще один массив с индексами и при сортировки основного массива менять местами значения элементов массива с индексами соответсвенно смене значений основного массива
slba
82
slba  
 Дмитрий за ответ спасибо! Но не получается, если возможно прошу элементарный пример.
Dmitry Fedoseev
44508
Dmitry Fedoseev  
//+------------------------------------------------------------------+
//|                                                       s_Sort.mq4 |
//|                                                                  |
//+------------------------------------------------------------------+
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   double PriceArray[];//будем сортировать этот массив
   ArrayResize(PriceArray,10);//массив будет состоять из 10-и элементов
 
   //заполним массив значения цен закрытия с последних 10 баров
   for(int i=0;i<ArraySize(PriceArray);i++){
       PriceArray[i]=Close[i];  
     }
   
      //имеем несортированый массив PriceArray[]
   
      //выводим в журнал несортированный массив
      Print("Несортированный:");
      for(i=0;i<ArraySize(PriceArray);i++)
        {
         Print(i,"-",PriceArray[i]);
        } 
      //создадим массив для индекстов
      int IndexArray[];
      ArrayResize(IndexArray,ArraySize(PriceArray));//массив для 
      // индексов должен состоять из такого же количества элементов 
      // как и сортируемый массив
      //заполняем массив для индексов индексами  
      for(i=0;i<ArraySize(IndexArray);i++)
        {
          IndexArray[i]=i;  
        }   
      //две временные переменных, которые потребуются при обмене значений сортируемых массивов
      double tmpPriceArray;
      int tmpIndexArray;
      //сортируем
      for(i=0;i<ArraySize(PriceArray);i++)
        {
          for(int j=0;j<ArraySize(PriceArray);j++)
            {
              //для сортировки в 
              //обратном порядке 
              // поставить   ">" 
              if(PriceArray[j]<PriceArray[i])
                {
                  tmpPriceArray=PriceArray[j];
                  tmpIndexArray=IndexArray[j];
                  PriceArray[j]=PriceArray[i];
                  IndexArray[j]=IndexArray[i];
                  PriceArray[i]=tmpPriceArray;
                  IndexArray[i]=tmpIndexArray;            
                }
            }   
        }
      //выводим в журнал сортированный массив
      Print("Сортированный:");
      for(i=0;i<ArraySize(PriceArray);i++)
        {
          Print(IndexArray[i],"-",PriceArray[i]);
        }
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
Dmitry Fedoseev
44508
Dmitry Fedoseev  
только нормализацию не забудь при сравении
Glaswegian
485
Glaswegian  
slba:

Новичок.

Вопрос по MQL4: возможно ли сохранить индексы чисел исходного одномерного массива после его сортировки по возрастанию или убыванию ?
Необходимость в идентификации при выводе Print. (Значения некоторых чисел исходного массива могут быть одинаковыми).
Если возможно, прошу помочь примером.

ArraySort, к счастью, дает такую прекрасную возможность:
int ArraySort( & array[], int count=WHOLE_ARRAY, int start=0, int sort_dir=MODE_ASCEND)
Сортировка числовых массивов по первому измерению. Массивы-таймсерии не могут быть отсортированы.

Можно использовать это свойство сортировки по первому измерению примерно вот так:
int arrayWithIndexes[ARRAY_SIZE][2]; // создаем двумерный массив ARRAY_SIZE 'строк' на 2 'столбца' .
                                                       // первый столбец используется для собственно значения
                                                       // второй для индекса до сортировки
 
// Инициализируем индексы
int i = ArraySize(arrayWithIndexes);
 
while (i > 0)
{
    i--;
    arrayWithIndexes[i][1] = i;
}

// Здесь код работы с первым элементом, arrayWithIndexes[n][0] = и так далее
// ...
 
ArraySort(arrayWithIndexes); // Сортируем массив по значениям в первом элементе.
 
int index = arrayWithIndexes[n][1]; // Получаем индекс в исходном массиве до сортировки.

Массив может быть любого типа, кроме bool. Для строкового массива нужно будет явно преобразовывать индексы в строки.
Glaswegian
485
Glaswegian  
Исправил ошибку при инициализации индексов - в цикле while отсутствовал декремент i--;
slba
82
slba  
Integer писал (а):
только нормализацию не забудь при сравении

Спасибо Дмитрий за пример мне он пригодиться и не только для понимания вопроса. В моем варианте числовые массивы не являются таймсериями, поэтому вариант двумерного массива для меня был более удобен ( пояснения Irtron), все получилось без проблем.
Извиняюсь за поздний ответ был в командировке: работа-работой а форекс-форексом.
slba
82
slba  
Irtron:
Исправил ошибку при инициализации индексов - в цикле while отсутствовал декремент i--;

Спасибо за пример все получилось без проблем. Единствено, что я заменил цикл while на for. С while почему-то при выводе на Print индексация происходит нормально, но память отводится под весь размер двумерного массива.
Извиняюсь за поздний ответ был в командировке: работа-работой а форекс-форексом.
Glaswegian
485
Glaswegian  
slba писал (а):
Спасибо за пример все получилось без проблем. Единствено, что я заменил цикл while на for. С while почему-то при выводе на Print индексация происходит нормально, но память отводится под весь размер двумерного массива.
Да, ArraySize, в отличие от ArrayResize, оперирует не длиной первого измерения, а размером массива, учитывающим все измерения.
В моем примере должно было быть
   // Инициализируем индексы
   int i = ArraySize(arrayWithIndexes) / 2;
slba
82
slba  
Irtron:
slba писал (а):
Спасибо за пример все получилось без проблем. Единствено, что я заменил цикл while на for. С while почему-то при выводе на Print индексация происходит нормально, но память отводится под весь размер двумерного массива.
Да, ArraySize, в отличие от ArrayResize, оперирует не длиной первого измерения, а размером массива, учитывающим все измерения.
В моем примере должно было быть
   // Инициализируем индексы
   int i = ArraySize(arrayWithIndexes) / 2;

Понял. Спасибо!
12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий