queues - merge sort algoritmo c++
Fusionando Rangos En C++ (6)
Tengo una lista de rangos de final cerrado únicos aleatorios ordenados R 0 ... R n-1 donde
R i = [r1 i , r2 i ] (r1 i <= r2 i )
Posteriormente, algunos de los rangos se superponen (parcial o totalmente) y, por lo tanto, requieren fusión.
Mi pregunta es, ¿cuáles son los mejores algoritmos o técnicas utilizadas para fusionar dichos rangos? Los ejemplos de tales algoritmos o enlaces a bibliotecas que realizan tal operación de fusión serían excelentes.
La respuesta de jetro contiene un error. Debería ser
if (current.second > it->first){
current.second = std::max(current.second, it->second);
} else {
Lo que debes hacer es:
Ordene los artículos lexicográficamente donde la clave de rango es [r_start, r_end]
Iterar la lista ordenada y comprobar si el elemento actual se superpone con el siguiente. Si extiende el elemento actual para que sea r [i] .start, r [i + 1] .end, y pase al siguiente elemento. Si no se superponen, agregue el actual a la lista de resultados y pase al siguiente elemento.
Aquí hay un código de muestra:
vector<pair<int, int> > ranges;
vector<pair<int, int> > result;
sort(ranges.begin(),ranges.end());
vector<pair<int, int> >::iterator it = ranges.begin();
pair<int,int> current = *(it)++;
while (it != ranges.end()){
if (current.second > it->first){ // you might want to change it to >=
current.second = std::max(current.second, it->second);
} else {
result.push_back(current);
current = *(it);
}
it++;
}
result.push_back(current);
Mi algoritmo no usa espacio extra y también es liviano. He utilizado el enfoque de 2-pointer
. ''i'' sigue aumentando mientras que ''j'' hace un seguimiento del elemento actual que se está actualizando. Aquí está mi código:
bool cmp(Interval a,Interval b)
{
return a.start<=b.start;
}
vector<Interval> Solution::insert(vector<Interval> &intervals, Interval newInterval) {
int i,j;
sort(intervals.begin(),intervals.end(),cmp);
i=1,j=0;
while(i<intervals.size())
{
if(intervals[j].end>=intervals[i].start) //if overlaps
{
intervals[j].end=max(intervals[i].end,intervals[j].end); //change
}
else
{
j++;
intervals[j]=intervals[i]; //update it on the same list
}
i++;
}
intervals.erase(intervals.begin()+j+1,intervals.end());
return intervals;
}
El intervalo puede ser una clase o estructura pública con miembros de datos ''inicio'' y ''final''. Feliz codificación :)
O (n * log (n) + 2n):
- Haz un mapeo de
r1_i -> r2_i
, - QuickSort sobre el
r1_i
''s, -
r1_i
la lista para seleccionar para cada valorr1_i
valor más grande der2_i
, - con ese valor de
r2_i
puede omitir todos losr1_i
subsiguientes que sean más pequeños quer2_i
Un algoritmo simple sería:
- Ordenar los rangos por valores iniciales
- Iterar sobre los rangos de principio a fin, y cada vez que encuentre un rango que se superponga con el siguiente, combínelos
Boost.Icl puede ser de utilidad para usted.
La biblioteca ofrece algunas plantillas que puede usar en su situación:
- interval_set: implementa un conjunto como un conjunto de intervalos, combinando intervalos adyacentes.
- separate_interval_set: implementa un conjunto como un conjunto de intervalos, dejando separados los intervalos adyacentes
- split_interval_set - implementa un conjunto como un conjunto de intervalos - en la inserción los intervalos superpuestos se dividen
Hay un example para combinar intervalos con la biblioteca:
interval<Time>::type night_and_day(Time(monday, 20,00), Time(tuesday, 20,00));
interval<Time>::type day_and_night(Time(tuesday, 7,00), Time(wednesday, 7,00));
interval<Time>::type next_morning(Time(wednesday, 7,00), Time(wednesday,10,00));
interval<Time>::type next_evening(Time(wednesday,18,00), Time(wednesday,21,00));
// An interval set of type interval_set joins intervals that that overlap or touch each other.
interval_set<Time> joinedTimes;
joinedTimes.insert(night_and_day);
joinedTimes.insert(day_and_night); //overlapping in ''day'' [07:00, 20.00)
joinedTimes.insert(next_morning); //touching
joinedTimes.insert(next_evening); //disjoint
cout << "Joined times :" << joinedTimes << endl;
y la salida de este algoritmo:
Joined times :[mon:20:00,wed:10:00)[wed:18:00,wed:21:00)
Y aquí sobre la complejidad de sus algoritmos: