// test code for http://stackoverflow.com/questions/24542936/
#include <vector>
#include <set>
#include <algorithm>
#include <chrono>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
const int N = 20000;
// reused from https://i...content-available-to-author-only...e.com/MN7DYK
struct timer
{
typedef std::chrono::high_resolution_clock clock;
clock::time_point start_;
timer() : start_(clock::now()) {}
~timer()
{
std::cout
<< ((double)std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - start_).count() / 1000.)
<< "ms" << std::endl;
}
};
void test_vector() {
timer t;
std::vector<int> c;
// insert elements randomly while maintaining order
for(int i = 0; i < N; ++i) {
int r = rand();
// linear search for insert position
auto position = c.end();
for(auto it = c.begin(); it != c.end(); ++it) {
if(*it >= r) {
position = it;
break;
}
}
c.insert(position, r);
}
// remove randomly while maintaining order
for(auto i = c.size() - 1; i > 0; --i) {
auto it = c.begin();
std::advance(it, rand() % i);
c.erase(it);
}
}
void test_bsvector() {
timer t;
std::vector<int> c;
// insert elements randomly while maintaining order
for(int i = 0; i < N; ++i) {
int r = rand();
// binary search
c.insert(std::lower_bound(c.begin(), c.end(), r), r);
}
// remove randomly while maintaining order
for(auto i = c.size() - 1; i > 0; --i) {
auto it = c.begin();
std::advance(it, rand() % i);
c.erase(it);
}
}
void test_set() {
timer t;
std::set<int> c;
// insert elements randomly while maintaining order
for(int i = 0; i < N; ++i)
c.insert(rand()); // logarithmic search
// remove randomly while maintaining order
// if you have a faster algorithm, please share
for(auto i = c.size() - 1; i > 0; --i) {
auto it = c.begin();
std::advance(it, rand() % i);
c.erase(it);
}
}
using namespace __gnu_pbds;
typedef
tree<
int,
int,
std::less<int>,
rb_tree_tag,
tree_order_statistics_node_update>
map_t;
void test_ost() {
timer t;
map_t c;
// insert elements randomly while maintaining order
for(int i = 0; i < N; ++i) {
int r = rand();
c.insert(std::make_pair(r, r)); // logarithmic search
}
// remove randomly while maintaining order
for(auto i = c.size() - 1; i > 0; --i) {
c.erase(c.find_by_order(rand() % i));
}
}
int main() {
unsigned int seed = std::time(nullptr);
std::srand(seed);
std::cout << "order statistics tree: ";
test_ost();
std::srand(seed);
std::cout << "vector binary search: ";
test_bsvector();
std::srand(seed);
std::cout << "vector linear search: ";
test_vector();
std::srand(seed);
std::cout << "set: ";
test_set();
}