Сортировка / объединение связанных массивов - PullRequest
1 голос
/ 20 апреля 2011

Должен быть какой-то алгоритм, который сделает это проще, чем то, что я делаю ...

У меня есть два массива, каждый с двумя столбцами.Один столбец в обоих - это временная метка, а другой в обоих - это измерение.

Что нужно сделать, это превратить это в единый массив: отметка времени, измерение1, измерение2

временные метки часто не совпадают точно.В одном массиве может отсутствовать какое-либо значение в течение определенного периода времени, или временные метки могут быть отключены на незначительную величину (настолько незначительную, что было бы нормально назначить оба измерения одной и той же временной метке).известный способ сделать эту нечеткую операцию слияния?Простая функция общественного достояния ??

1 Ответ

1 голос
/ 20 апреля 2011

Начните с того, чтобы задать себе следующие вопросы: У массивов одинаковое количество элементов?Как вы хотите объединить два элемента с одной и той же отметкой времени?Как вы хотите объединить два элемента с разной отметкой времени?

Возможно, вам придется написать алгоритм самостоятельно.Что-то вроде этого было бы легко реализовать:

  1. Начните с сортировки каждого массива индивидуально по порядку отметки времени.
  2. Объявите два итератора в начале каждого входного массива соответственно, ипустой выходной массив.
  3. Затем вы проверяете, какой из массивов имеет самую раннюю временную метку.Назовите это РАНЬШЕ, а другое ПОЗЖЕ.
    • Если EARLY близко к LATE (менее чем на некоторую константу), вы применяете операцию слияния и вставляете результат в конец выходного массива.Увеличьте оба итератора и вернитесь к 3.
    • В противном случае, РАННЕЕ далеко от ПОЗДНО.Вам необходимо обработать пропущенное значение в массиве LATE, возможно, повторив предыдущее значение или интерполировав его с помощью некоторой функции.Решите вставлять или нет значение в выходной массив.В этом случае вы увеличиваете значение только РАННЕГО итератора массива и возвращаетесь к 3.
  4. Если вы достигли конца одного из массивов, остальная часть другого массива будет LATE.Вы можете интерпретировать это как отсутствующие значения, а также повторить или интерполировать измерения.
  5. Возвращать выходной массив.

~

OutputArray merge(InputArray& a, InputArray& b) {
    InputArray::iterator a_it = a.begin();
    InputArray::iterator b_it = b.begin();
    while(a_it != a.end() && b_it != b.end()) {
        InputArray::iterator& early = *a_it.timestamp < *b_it.timestamp ? a_it : b_it;
        InputArray::iterator& late = *a_it.timestamp < *b_it.timestamp ? b_it : a_it;
        if(*late.timestamp - *early.timestamp < TIMESTAMP_CLOSE_ENOUGH) {
            output.timestamp = (*late.timestamp + *early.timestamp) / 2; // mean value
            output.measure1 = *a_it.measure;
            output.measure2 = *b_it.measure;
            outputArray.push_back(output);
            a_it++; b_it++;
        }
        else {
            output.timestamp = *early.timestamp;
            output.measure1 = *a_it.timestamp < *b_it.timestamp ? *a_it.measure : outputArray.back.measure1; // previous value if missing
            output.measure2 = *a_it.timestamp < *b_it.timestamp ? outputArray.back.measure2 : *b_it.measure;
            outputArray.push_back(output);
            early++;
        }
    }

    InputArray::iterator& late = a_it != a.end() ? a_it : b_it;
    InputArray::iterator late_end = a_it != a.end() ? a.end() : b.end();
    while(late != late_end) {
            output.timestamp = *late.timestamp;
            output.measure1 = a_it != a.end() ? *a_it.measure : outputArray.back.measure1; // previous value if missing
            output.measure2 = a_it != a.end() ? outputArray.back.measure2 : *b_it.measure;
            outputArray.push_back(output);
            late++;
    }
    return outputArray;
}
...