-
Notifications
You must be signed in to change notification settings - Fork 0
/
SparseVector.tcc
126 lines (111 loc) · 2.9 KB
/
SparseVector.tcc
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
template <class T>
SparseVector<T>::SparseVector() {
v.clear();
r = Roaring();
}
template <class T>
SparseVector<T>::SparseVector(SparseVector<T> &&arg) : r(std::move(arg.r)), v(std::move(arg.v)) {};
template <class T>
SparseVector<T>::SparseVector(const SparseVector<T> &arg) : r(arg.r), v(arg.v) {};
template <class T>
SparseVector<T>& SparseVector<T>::operator=(SparseVector<T> &&other) {
r = std::move(other.r);
v = std::move(other.v);
return *this;
}
template <class T>
SparseVector<T>& SparseVector<T>::operator=(const SparseVector<T> &other) {
r = other.r;
v = other.v;
return *this;
}
// Warning:
// Worst case performance is O(N).
// It is recommended to insert items in order of ascending indices.
template <class T>
void SparseVector<T>::insert(size_t i, const T &elem) {
size_t idx;
if (r.contains(i)) {
idx = r.rank(i) - 1;
v[i] = elem;
} else {
idx = r.rank(i);
r.add(i);
if (v.size() == idx) {
v.push_back(elem);
} else {
v.emplace(v.begin() + idx, elem);
}
}
}
template <class T>
void SparseVector<T>::insert(const std::pair<size_t, T> &elem) {
insert(elem.first, elem.second);
}
// Warning:
// Worst case performance is O(N).
// It is recommended to remove items in order of descending indices.
template <class T>
T SparseVector<T>::remove(size_t i) {
T t;
if (r.contains(i)) {
size_t idx = r.rank(i) - 1;
t = v[idx];
r.remove(i);
v.erase(v.begin()+idx);
}
return t;
}
template <class T>
void SparseVector<T>::clear() {
v.clear();
r = Roaring();
}
template <class T>
void SparseVector<T>::getElements(std::vector<std::pair<uint32_t, T> > &elems) {
if (r.isEmpty()) return;
elems.reserve(r.cardinality());
uint32_t i = 0;
for (const auto &idx : r) {
elems.push_back(std::pair<uint32_t, T>(idx, v[i]));
++i;
}
}
// Returns a new T if element is not in the sparse vector
template <class T>
T SparseVector<T>::get(size_t i) const {
if (r.contains(i)) {
return v[r.rank(i) - 1];
}
return T();
}
// Returns def if element is not in the sparse vector
template <class T>
T SparseVector<T>::get(size_t i, const T &def) const {
if (r.contains(i)) {
return v[r.rank(i) - 1];
}
return def;
}
template <class T>
bool SparseVector<T>::contains(size_t i) const {
return r.contains(i);
}
template <class T>
bool SparseVector<T>::isEmpty() const {
return r.isEmpty();
}
template <class T>
T& SparseVector<T>::operator[] (size_t i) {
if (r.contains(i)) {
return v[r.rank(i) - 1];
}
throw std::invalid_argument("Index not present in SparseVector.");
}
template <class T>
const T& SparseVector<T>::operator[] (size_t i) const {
if (r.contains(i)) {
return v[r.rank(i) - 1];
}
throw std::invalid_argument("Index not present in SparseVector.");
}