#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <unordered_set>
#include <string>
#include <algorithm>
#include <numeric>
#include <random>
#include <chrono>
using namespace std;
using namespace std::chrono;
// Returns shuffled sequence of unique numbers of specified size, with values from start to start + size - 1.
vector<int> shuffled_sequence(int size, int start = 0) {
vector<int> result(size);
iota(result.begin(), result.end(), start);
random_shuffle(result.begin(), result.end());
return result;
}
// Returns sequence of random numbers of specified size, with values from 0 to max.
vector<int> random_sequence(int size, int max) {
random_device rd;
default_random_engine generator(rd());
uniform_int_distribution<int> distribution(0, max);
vector<int> result;
for (int i = 0; i < size; i++) {
result.push_back(distribution(generator));
}
return result;
}
// ��������� ������������� ��� �������
template<typename Container>
void insert_element(Container& container, int elem, bool insert_at_beginning) {
if (insert_at_beginning) {
container.insert(container.begin(), elem);
} else {
container.push_back(elem);
}
}
// ������������� ��� set
template<>
void insert_element<set<int>>(set<int>& container, int elem, bool insert_at_beginning) {
container.insert(elem);
}
// ������������� ��� unordered_set
template<>
void insert_element<unordered_set<int>>(unordered_set<int>& container, int elem, bool insert_at_beginning) {
container.insert(elem);
}
template<typename Container>
void test_insertion(const vector<int>& elements, const string& container_name, bool insert_at_beginning = false) {
Container container;
auto start = high_resolution_clock::now();
for (const auto& elem : elements) {
insert_element(container, elem, insert_at_beginning);
}
auto end = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(end - start);
string operation = insert_at_beginning ? "insert at beginning" : "insert at end";
if (container_name == "set" || container_name == "unordered_set") {
operation = "insert";
}
cout << container_name << " " << operation << " time for " << elements.size()
<< " elements: " << duration.count() << " microseconds" << endl;
}
// ��������� ������������� ��� ������
template<typename Container>
int search_in_container(Container& container, const vector<int>& search_elements) {
int hits = 0;
for (const auto& elem : search_elements) {
auto it = find(container.begin(), container.end(), elem);
if (it != container.end()) {
hits++;
}
}
return hits;
}
// ������������� ��� set
template<>
int search_in_container<set<int>>(set<int>& container, const vector<int>& search_elements) {
int hits = 0;
for (const auto& elem : search_elements) {
auto it = container.find(elem);
if (it != container.end()) {
hits++;
}
}
return hits;
}
// ������������� ��� unordered_set
template<>
int search_in_container<unordered_set<int>>(unordered_set<int>& container, const vector<int>& search_elements) {
int hits = 0;
for (const auto& elem : search_elements) {
auto it = container.find(elem);
if (it != container.end()) {
hits++;
}
}
return hits;
}
template<typename Container>
void test_search(Container& container, const vector<int>& search_elements, const string& container_name) {
auto start = high_resolution_clock::now();
int hits = search_in_container(container, search_elements);
auto end = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(end - start);
cout << container_name << " search time for " << search_elements.size()
<< " elements: " << duration.count() << " microseconds (hits: " << hits << ")" << endl;
}
int main() {
const int M = 10000; // Number of search operations
vector<int> sizes = {10, 100, 1000, 10000, 100000};
for (int size : sizes) {
cout << "\n=== Testing with " << size << " elements ===" << endl;
const auto elems_to_add = shuffled_sequence(size);
const auto elems_to_search = random_sequence(M, 2 * size);
// Test vector - insert at end
test_insertion<vector<int>>(elems_to_add, "vector", false);
// Test vector - insert at beginning
test_insertion<vector<int>>(elems_to_add, "vector", true);
// Test list - insert at end
test_insertion<list<int>>(elems_to_add, "list", false);
// Test list - insert at beginning
test_insertion<list<int>>(elems_to_add, "list", true);
// Test set
test_insertion<set<int>>(elems_to_add, "set");
// Test unordered_set
test_insertion<unordered_set<int>>(elems_to_add, "unordered_set");
cout << "--- Search tests ---" << endl;
// Prepare containers for search tests
vector<int> vec_end(elems_to_add.begin(), elems_to_add.end());
vector<int> vec_begin;
for (auto it = elems_to_add.rbegin(); it != elems_to_add.rend(); ++it) {
vec_begin.push_back(*it);
}
list<int> lst_end(elems_to_add.begin(), elems_to_add.end());
list<int> lst_begin(elems_to_add.begin(), elems_to_add.end());
set<int> st(elems_to_add.begin(), elems_to_add.end());
unordered_set<int> ust(elems_to_add.begin(), elems_to_add.end());
// Test search operations
test_search(vec_end, elems_to_search, "vector (end)");
test_search(vec_begin, elems_to_search, "vector (begin)");
test_search(lst_end, elems_to_search, "list (end)");
test_search(lst_begin, elems_to_search, "list (begin)");
test_search(st, elems_to_search, "set");
test_search(ust, elems_to_search, "unordered_set");
}
return 0;
}