Объединение интервалов

258
02 ноября 2017, 07:09

Имеется n-промежутков, вида: [a1,b1];[a2,b2];...;[an,bn]. Необходимо получить объединение данной последовательности промежутков. Например:

на входе: [1,2];[2,3];[3,4] тогда на выходе: [1,4]

на входе: [1,2];[2,3];[3,4];[5,6];[6;7] тогда на выходе: [1,4];[5,7]

и так далее

Я решила эту задачу простым циклом с проверкой всех возможных вариантов объединение промежутков. Но! Я не совсем уверена в корректности, вдруг найдется такой промежуток, для которого алгоритм выдаст неправильный результат.

struct Interval{
    double a, b;
    Interval(){}
    Interval(double A, double B){a = A; b = B;}
};
vector<Interval> H;
   for(int k = 0; k < X.size(); ++k){
       double a = X[k].a;
       double b = X[k].b;
       if(b-a < eps) continue;
       for(int i = k; i < X.size()-1; ++i){
          if(fabs(X[i].b-X[i+1].a) < eps){
             b = X[i+1].b;
             k = i+1;
             continue;
          }
          else break;
       }
    H.push_back(Interval(a, b));
}

У меня появилась идея рекурсивного алгоритма: рассматриваются два соседних промежутка, если I[i].b == I[i+1].a, то объединить два промежутка в один и получить [I[i].a, I[i+1].b]. Но, к сожалению, все мои реализации выдают неверный ответ. Буду рада, если предложите какие-то идеи по решению данной задачи.

Answer 1

Преобразуйте интервалы в вариант значение-действие, где действие = 1 для начала, и -1 для конца. Отсортируйте по значению. Элементы с равным значением "соберите" в один с суммарным действием. Потом пройдите по полученному массиву, считая сумму с накоплением для действия. Там, где был 0, стало 1 - начало итогового объединённого интервала, где наоборот - конец.

UPDATE:

например, на входе: [1,3];[2,3];[3,4];[5,6];[6;7]

Конвертируем в:

1  1
3 -1
2  1
3 -1
3  1
4 -1
5  1
6 -1
6  1
7 -1

Сжимаем элементы с равным Значением

1  1
2  1
3 -1
4 -1
5  1
6  0
7 -1

Считаем сумму с накоплением

1  1  1  - начало
2  1  2
3 -1  1
4 -1  0  - конец
5  1  1  - начало
6  0  1
7 -1  0  - конец

Результат: [1;4],[5,7]

READ ALSO
Пирамидальная сортировка на с++

Пирамидальная сортировка на с++

Хочу сделать сортировку пирамидальную (обратную) То есть что бы массив в котором есть числа 4,5,3,0 отсортировало не так 0,3,4,5, а так 5,4,3,0Вот функции...

258
Запуск процесса в памяти в бесконечном цикле

Запуск процесса в памяти в бесконечном цикле

Написать программу, которая бы запускала в памяти еще один процесс и оставляла бы его работать в бесконечном циклеПри повторном запуске...

207
Исключить нажатие кнопок по событию keyup

Исключить нажатие кнопок по событию keyup

Всем приветЕсть такой скрипт

265