15 template <
class T,
class I>
18 const std::vector<T>&
x;
24 static const int radix_width = 8;
26 static const int total_width =
sizeof(T) * 8;
28 static const int num_keys = (1 << radix_width);
30 static const int mask = num_keys - 1;
31 size_t key(T x,
int k) {
return (x >> k) & mask; }
33 radix(
const std::vector<T>& x) : x(x) {
34 static_assert(T(-1) > T(0),
"Value type must be unsigned");
35 static_assert(total_width % radix_width == 0,
36 "Value width must be a multiple of radix width");
38 template <
bool get_order>
40 T bitwise_min = ~0, bitwise_max = 0;
41 for (
size_t i = 0; i < x.size(); i++) {
47 x_order.resize(x.size() * get_order);
48 for (
size_t i = 0; i < x_order.size(); i++) x_order[i] = i;
50 std::vector<size_t> count(num_keys);
51 std::vector<size_t> pos(num_keys);
53 std::vector<I> y_order(x.size() * get_order);
54 std::vector<T> y_sort(x.size());
55 for (
size_t k = 0; k < total_width; k += radix_width) {
56 if (key(bitwise_min, k) == key(bitwise_max, k))
continue;
58 std::fill(count.begin(), count.end(), 0);
59 for (
size_t i = 0; i < x.size(); i++) {
60 count[key(x[i], k)]++;
63 std::fill(pos.begin(), pos.end(), 0);
64 for (
size_t i = 1; i < pos.size(); i++) {
65 pos[i] = pos[i - 1] + count[i - 1];
67 for (
size_t i = 0; i < x.size(); i++) {
68 T x_sort_i = x_sort[i];
69 size_t& j = pos[key(x_sort_i, k)];
72 if (get_order) y_order[j] = x_order[i];
75 std::swap(x_sort, y_sort);
76 std::swap(x_order, y_order);
79 std::vector<T> sort() {
83 std::vector<I> order() {
89 std::vector<I> ans(x_order.size());
90 for (
size_t i = 0; i < ans.size(); i++) ans[i] = i;
91 for (
size_t i = 1; i < x_sort.size(); i++) {
92 if (x_sort[i - 1] == x_sort[i]) {
93 ans[x_order[i]] = ans[x_order[i - 1]];
100 template <
class I,
class T>
101 std::vector<I> order(
const std::vector<T>& x) {
107 template <
class I,
class T>
115 template <
class I,
class T>
116 std::vector<I>
factor(
const std::vector<T>& x) {
117 std::vector<I> y = first_occurance<I>(x);
118 std::vector<I> tab(y.size());
119 for (
size_t i = 0, k = 0; i < y.size(); i++) {
129 #endif // HAVE_RADIX_HPP Radix based sorting and first_occurance.
std::vector< T > x_sort
Output: sort(x)
const std::vector< T > & x
Reference to the input vector.
Simple radix sort implementation.
std::vector< I > factor(const std::vector< T > &x)
Replace each element in a vector by an integer code such that x[i] == x[j] implies f[i] == f[j] ...
std::vector< I > first_occurance(const std::vector< T > &x)
For each element of a vector find the index of its first occurance from the left. ...
std::vector< I > x_order
Output: order(x) permutation.