Advertisement
Petrovi4

CopyIfUnordered

Aug 29th, 2022
837
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.77 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <numeric>
  4. #include <random>
  5. #include <string>
  6. #include <string_view>
  7. #include <vector>
  8. #include <execution>
  9. #include <mutex>
  10. #include <future>
  11.  
  12. #include "log_duration.h"
  13.  
  14. using namespace std;
  15.  
  16. string GenerateWord(mt19937& generator, int max_length) {
  17.     const int length = uniform_int_distribution(1, max_length)(generator);
  18.     string word;
  19.     word.reserve(length);
  20.     for (int i = 0; i < length; ++i) {
  21.         word.push_back(uniform_int_distribution<>('a', 'z')(generator));
  22.     }
  23.     return word;
  24. }
  25.  
  26. template <template <typename> typename Container>
  27. Container<string> GenerateDictionary(mt19937& generator, int word_count, int max_length) {
  28.     vector<string> words;
  29.     words.reserve(word_count);
  30.     for (int i = 0; i < word_count; ++i) {
  31.         words.push_back(GenerateWord(generator, max_length));
  32.     }
  33.     return Container(words.begin(), words.end());
  34. }
  35.  
  36. template <typename Strings, typename Predicate, typename Function>
  37. void Test(string_view mark, const Strings& strings, Predicate predicate, Function function) {
  38.     LOG_DURATION(mark);
  39.     const auto result = function(strings, predicate);
  40.     cout << result.size() << " " << result[5].substr(0, 5) << endl;
  41. }
  42.  
  43. #define TEST(function) \
  44.     Test(#function, strings, predicate, function<vector<string>, decltype(predicate)>)
  45.  
  46. template <typename Container, typename Predicate>
  47. vector<typename Container::value_type> CopyIfUnordered(const Container& container, Predicate predicate) {
  48.     std::vector<typename Container::value_type> result;
  49.     result.reserve(container.size());
  50.     std::mutex value_mutex;    
  51.    
  52.  
  53.     std::for_each(std::execution::par, container.begin(), container.end(), [&result, predicate, &value_mutex](auto value) {
  54.         typename Container::value_type* pushed_ptr;
  55.         if (predicate(value)) {
  56.  
  57.             {
  58.                 std::lock_guard guard(value_mutex);
  59.                 pushed_ptr = &result.emplace_back();
  60.             }
  61.  
  62.             *pushed_ptr = value;
  63.         }
  64.         });
  65.  
  66.     return result;
  67. }
  68.  
  69. template <typename Container, typename Predicate>
  70. vector<typename Container::value_type> CopyIfUnorderedConsistent(const Container& container,
  71.     Predicate predicate) {
  72.     vector<typename Container::value_type> result;
  73.     for (const auto& value : container) {
  74.         if (predicate(value)) {
  75.             result.push_back(value);
  76.         }
  77.     }
  78.     return result;
  79. }
  80.  
  81. int main() {
  82.     vector<int> numbers(1'000);
  83.    iota(numbers.begin(), numbers.end(), 0);
  84.  
  85.    {
  86.        const vector<int> even_numbers = CopyIfUnordered(numbers, [](int number) {
  87.            return number % 2 == 0;
  88.            });
  89.        for (const int number : even_numbers) {
  90.            cout << number << " "s;
  91.        }
  92.        cout << endl;
  93.        // выведет все чётные числа от 0 до 999
  94.  
  95.        mt19937 generator;
  96.  
  97.        const auto strings = GenerateDictionary<vector>(generator, 50'000, 3000);
  98.         auto predicate = [](const string& s) {
  99.             return count(s.begin(), s.end(), 'a') < 100;
  100.         };
  101.  
  102.         TEST(CopyIfUnordered);
  103.     }
  104.  
  105.     {
  106.         const vector<int> even_numbers = CopyIfUnorderedConsistent(numbers, [](int number) {
  107.             return number % 2 == 0;
  108.             });
  109.         for (const int number : even_numbers) {
  110.             cout << number << " "s;
  111.         }
  112.         cout << endl;
  113.         // выведет все чётные числа от 0 до 999
  114.  
  115.         mt19937 generator;
  116.  
  117.         const auto strings = GenerateDictionary<vector>(generator, 50'000, 3000);
  118.        auto predicate = [](const string& s) {
  119.            return count(s.begin(), s.end(), 'a') < 100;
  120.        };
  121.  
  122.        TEST(CopyIfUnorderedConsistent);
  123.    }
  124.  
  125.    return 0;
  126. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement