Как рационально объединить большие массивы структур.

 

Здравствуйте, уважаемые участники форума.

У меня есть 2 очень больших массива (может быть до миллиона элементов) структур вида

struct Str_Arr
  {
   datetime          Time;
   double            Price;
  }

Их нужно объединить так, чтобы недостающие элементы (по времени) из одного массива попали в другой. Пример на картинке. Сохранить последовательность по времени необходимо.

Подскажите, как это можно сделать максимально рационально (максимально быстро).


 
Sergey Savinkin:

Здравствуйте, уважаемые участники форума.

У меня есть 2 очень больших массива (может быть до миллиона элементов) структур вида

Их нужно объединить так, чтобы недостающие элементы (по времени) из одного массива попали в другой. Пример на картинке. Сохранить последовательность по времени необходимо.

Подскажите, как это можно сделать максимально рационально (максимально быстро).


Миллион - это вовсе не большие данные. Структура будет занимать 16 байт, массив 16 Мб. Создаем отдельный С, а потом довольно просто.

Делаем цикл по одной секунде, если на итерации находим данные с таким же временем в одном из массивов, пишем их в С, у А и В должны быть счетчики индексов

 
оба массива упорядочены?
 
TheXpert:
оба массива упорядочены?

Да, по времени.

 
TheXpert:
оба массива упорядочены?

да, это важный вопрос, похоже да, судя по рисунку

 

Я чего-то не понял ?

Кто нам мешает слить массивы и отсортировать их по времени ?

Если массивы уже отсортированы - то и сортировать не надо - пишем алгоритм сливания с двумя указателями на каждом массиве, просматриваем следующий элемент на обоих, и скидываем в результирующий массив более ранний элемент, одновременно передвигая указатель на этом исходном массиве.

 

Вот нашел:

public static int[] merge(int[] a, int[] b) {
    int[] answer = new int[a.length + b.length];
    int i = a.length - 1, j = b.length - 1, k = answer.length;

    while (k > 0)
        answer[--k] =
                (j < 0 || (i >= 0 && a[i] >= b[j])) ? a[i--] : b[j--];
    return answer;
}

Весьма компактная и неплохая реализация на java.

Хм... Да мне самому иногда такая штука требуется... Сейчас подредактирую под свои "внутренние MQL-стандарты". А то мне "вопросик" не нравится, да и оформление немного непривычно

 
Sergey Savinkin:

Да, по времени.

как-то так (не проверял)

void OnStart()
{
   Str_Arr arr1[];
   Str_Arr arr2[];
   
   Str_Arr res[];
   
   int size1 = ArraySize(arr1);
   int size2 = ArraySize(arr2);
   int sizeRes = size1 + size2;
   ArrayResize(res, sizeRes);
   int pos1 = 0; pos2 = 0; posRes = 0;
   for (int i = 0; i < sizeRes; i++)
   {
      if (pos1 >= size1)
      {
         res[posRes++] = arr2[pos2++];
         continue;
      }
      
      if (pos2 >= size2)
      {
         res[posRes++] = arr1[pos1++];
         continue;
      }

      if (arr1[pos1].Time < arr2[pos2].Time)
      {
         res[posRes++] = arr1[pos1++];
      }
      else
      {
         res[posRes++] = arr2[pos2++];
      }
   }
}
 
Спасибо за ответы. Надо убегать. Проверю вечером.
 
TheXpert:

как-то так (не проверял)

Не работает. Вот это:

#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property script_show_inputs 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
struct Str_Arr
  {
   datetime          Time;
   double            Price;
  }
;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
{
   Str_Arr arr1[];
   Str_Arr arr2[];
   
   Str_Arr res[];
   ArrayResize(arr1, 5);
   arr1[0].Time = TimeCurrent()+0;
   arr1[0].Price = 1;
   arr1[1].Time = TimeCurrent()+1;
   arr1[1].Price = 1;
   arr1[2].Time = TimeCurrent()+2;
   arr1[2].Price = 2;
   arr1[3].Time = TimeCurrent()+3;
   arr1[3].Price = 3;
   arr1[4].Time = TimeCurrent()+4;
   arr1[4].Price = 4;
 
   ArrayResize(arr2, 4);
   arr1[0].Time = TimeCurrent()+0;
   arr1[0].Price = 1;
   arr1[1].Time = TimeCurrent()+3;
   arr1[1].Price = 3;
   arr1[2].Time = TimeCurrent()+4;
   arr1[2].Price = 4;
   arr1[3].Time = TimeCurrent()+5;
   arr1[3].Price = 5;
  
   int size1 = ArraySize(arr1);
   int size2 = ArraySize(arr2);
   int sizeRes = size1 + size2;
   ArrayResize(res, sizeRes);
   int pos1 = 0, pos2 = 0, posRes = 0;
   for (int i = 0; i < sizeRes; i++)
   {
      if (pos1 >= size1)
      {
         res[posRes++] = arr2[pos2++];
         continue;
      }
      
      if (pos2 >= size2)
      {
         res[posRes++] = arr1[pos1++];
         continue;
      }

      if (arr1[pos1].Time < arr2[pos2].Time)
      {
         res[posRes++] = arr1[pos1++];
      }
      else
      {
         res[posRes++] = arr2[pos2++];
      }
   }
   ArrayPrint(res);
}//+------------------------------------------------------------------+

Выдает вот это:


 
Georgiy Merts:

Вот нашел:

Весьма компактная и неплохая реализация на java.

Хм... Да мне самому иногда такая штука требуется... Сейчас подредактирую под свои "внутренние MQL-стандарты". А то мне "вопросик" не нравится, да и оформление немного непривычно

Спасибо за вариант. Но я еще не так хорошо разбираюсь в ООП. Не могли бы сделать чуть читабельнее? Спасибо.