-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrange.cpp
89 lines (73 loc) · 2.21 KB
/
range.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "range.h"
#include <algorithm>
#include <set>
#include <queue>
#include <cassert>
#include <numeric>
using namespace std;
void clusterRanges(const vector<IRange> &ranges, std::vector<IdCluster> &clusters)
{
vector<IRangeEndPoint> endPoints;
for (size_t i = 0; i < ranges.size(); ++i) {
endPoints.push_back({ranges[i].start, i, true});
endPoints.push_back({ranges[i].end, i, false});
}
sort(endPoints.begin(), endPoints.end());
set<size_t> usedIds;
queue<size_t> buffer;
for (auto it = endPoints.begin(); it != endPoints.end(); ++it) {
if ((*it).isStart) buffer.push((*it).ownerId);
else {
if (usedIds.count((*it).ownerId)) continue;
IdCluster clu;
while (!buffer.empty()) {
clu.push_back(buffer.front());
usedIds.insert(buffer.front());
buffer.pop();
}
if (!clu.empty()) clusters.push_back(clu);
}
}
IdCluster clu;
while (!buffer.empty()) {
clu.push_back(buffer.front());
usedIds.insert(buffer.front());
buffer.pop();
}
if (!clu.empty()) clusters.push_back(clu);
}
void append(size_t startIndex, size_t endIndex, std::vector<IdCluster> &clusters)
{
IdCluster buffer(endIndex - startIndex);
std::iota(std::begin(buffer), std::end(buffer), startIndex);
clusters.push_back(buffer);
}
void clusterRanges2(const vector<IRange> &ranges, std::vector<IdCluster> &clusters)
{
size_t startIndex = 0;
for (size_t i = 1; i < ranges.size(); ++i) {
if (!ranges[i-1].overlaps(ranges[i])) {
append(startIndex, i, clusters);
startIndex = i;
}
}
append(startIndex, ranges.size(), clusters);
}
int IRange::length() const
{
return end - start + 1;
}
bool IRange::operator<(const IRange &other) const
{
if (start != other.start) return start < other.start;
return end < other.end;
}
bool IRange::overlaps(const IRange &other) const
{
return (start >= other.start && start < other.end) ||
(other.start >= start && other.start < end);
}
bool IRangeEndPoint::operator<(const IRangeEndPoint &other) const
{
return position < other.position;
}