Я пытался сделать это упражнение сам, но не смог заставить его работать должным образом для отрицательных интервалов.
Потом внедрил версию от geeksforgeeks и у меня получается то же самое. Вот логика, стоящая за этим:
1. Sort the intervals based on increasing order of
starting time.
2. Push the first interval on to a stack.
3. For each interval do the following
a. If the current interval does not overlap with the stack
top, push it.
b. If the current interval overlaps with stack top and ending
time of current interval is more than that of stack top,
update stack top with the ending time of current interval.
4. At the end stack contains the merged intervals.
.cpp
#include <iostream>
#include <algorithm>
#include <stack>
#include "Header.h"
bool functieComparareIntervalCrescator(Interval interval1, Interval interval2)
{
return interval1.lo < interval2.lo;
}
void citire(int& n, Interval vectorIntervale[])
{
std::cin >> n;
for (int i = 0; i < n; i++)
{
vectorIntervale[i].citire();
}
}
void afisareStack(std::stack<Interval> stivaIntervale)
{
int n = stivaIntervale.size();
for (int i = 0; i < n; i++)
{
std::cout << stivaIntervale.top().lo << " " << stivaIntervale.top().hi << std::endl;
stivaIntervale.pop();
}
}
void determinareReuniune(int n, Interval vectorIntervale[])
{
std::sort(vectorIntervale, vectorIntervale + n, functieComparareIntervalCrescator);
std::stack<Interval> stivaIntervale;
stivaIntervale.push(vectorIntervale[0]);
for (int i = 1; i < n; i++)
{
if (vectorIntervale[i].lo > stivaIntervale.top().lo && vectorIntervale[i].lo < stivaIntervale.top().hi)
{
if (vectorIntervale[i].hi > stivaIntervale.top().hi)
{
stivaIntervale.top().hi = vectorIntervale[i].hi;
}
}
else
{
stivaIntervale.push(vectorIntervale[i]);
}
}
afisareStack(stivaIntervale);
}
int main()
{
int n;
Interval vectorIntervale[100];
citire(n, vectorIntervale);
determinareReuniune(n, vectorIntervale);
}
header.cpp
#include "Header.h"
#include <iostream>
void Interval::citire()
{
std::cin >> lo >> hi;
}
#pragma once
struct Interval {
int lo, hi;
void citire();
};
Для ввода:
5
2 4 1 3 5 8 10 12 6 9
Я получаю правильный ответ.
Однако, если я изменю ввод на отрицательные числа, например
5
-2 -4 -1 -3 -5 -8 -10 -12 -6 -9
вывод
-6 -9
-10 -12
-5 -8
-1 -3
-2 -4
что точно не правильно.
Вот реализация от GeeksForGeeks, очень похожая на мою. https://www.geeksforgeeks.org/merging-intervals/
Если вы скопируете и вставите их код, он все равно не будет работать должным образом.
Как я могу исправить свой код, чтобы он также мог правильно работать с отрицательными интервалами?
Спасибо.
//редактировать: Я забыл добавить часть сортировки. Я добавил его в свой код, и он все еще не работает.
Когда вы читаете ввод, вы делаете:
void Interval::citire()
{
std::cin >> lo >> hi;
}
А вы предполагаете, что lo < hi
. Однако ваш ввод с негативами:
5
-2 -4 -1 -3 -5 -8 -10 -12 -6 -9
И все интервалы имеют сначала большее число, а затем меньшее. Либо ваш ввод недействителен, и он должен быть:
5
-4 -2 -3 -1 -8 -5 -12 -10 -9 -6
Или вам нужно отсортировать границы после чтения ввода:
void Interval::citire()
{
int a,b;
std::cin >> a >> b;
lo = std::min(a,b);
hi = std::max(a,b);
}
Или (предложено Jarod42):
void Interval::citire()
{
int a,b;
std::cin >> a >> b;
std::tie(lo,hi) = std::minmax(a,b);
}
Возможно std::tie(lo, hi) = std::minmax(a, b);
.
@OctavianNiculescu положительные числа существенно не отличаются от отрицательных, и я не нашел в вашем коде места, где вы их различаете. Что именно вы изменили? Вам не нужно std::sort
"сортировать" два числа
@OctavianNiculescu, вы можете показать мне свой обновленный Interval::citire
здесь: godbolt.org, тогда, возможно, я смогу прокомментировать, но, не видя вашего кода, я не знаю, что вы сделали
Я добавил std::sort в determinareReuniune, поэтому мои интервалы сортируются в порядке возрастания (по левой/левой стороне интервала, чтобы быть более понятным). Я больше ничего не менял.
@OctavianNiculescu не сортирует интервалы, сортирует lo
и hi
каждого интервала (как я показал в ответе)
@OctavianNiculescu в коде вашего вопроса уже есть вызов std::sort
в determinareReuniune
, поэтому я не понимаю, что вы изменили
@OctavianNiculescu, пожалуйста, не меняйте вопрос после получения ответов. В данном случае это не большая проблема (потому что я не имею в виду эту сортировку), но я вызвал некоторую путаницу
@largest_prime_is_463035818 Мне очень жаль. Я просто забыл добавить эту часть, и я подумал, что это может понадобиться. Теперь понял :) спасибо за ответ
Я забыл про сортировку массива. Я также добавил std::sort в determinareReuniune, но все равно не получил ожидаемого результата.