Advertisement
Seredenko-V

LowerBound_with_3_ranges

Aug 6th, 2022
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.29 KB | None | 0 0
  1. #include <algorithm>
  2. #include <execution>
  3. #include <iostream>
  4. #include <future>
  5.  
  6. #include "log_duration.h"
  7.  
  8. using namespace std;
  9.  
  10. template <typename RandomAccessIterator, typename Value>
  11. RandomAccessIterator LowerBound(const execution::sequenced_policy&,
  12.     RandomAccessIterator range_begin, RandomAccessIterator range_end, const Value& value) {
  13.     auto left_bound = range_begin;
  14.     auto right_bound = range_end;
  15.     while (left_bound + 1 < right_bound) {
  16.         const auto middle = left_bound + (right_bound - left_bound) / 2;
  17.         if (*middle < value) {
  18.             left_bound = middle;
  19.         } else {
  20.             right_bound = middle;
  21.         }
  22.     }
  23.     if (left_bound == range_begin && !(*left_bound < value)) {
  24.         return left_bound;
  25.     } else {
  26.         return right_bound;
  27.     }
  28. }
  29.  
  30. template <typename RandomAccessIterator, typename Value>
  31. RandomAccessIterator LowerBound(RandomAccessIterator range_begin, RandomAccessIterator range_end,
  32.     const Value& value) {
  33.     return LowerBound(execution::seq, range_begin, range_end, value);
  34. }
  35.  
  36. template <typename RandomAccessIterator, typename Value>
  37. RandomAccessIterator LowerBound(const execution::parallel_policy&, RandomAccessIterator range_begin,
  38.     RandomAccessIterator range_end, const Value& value) {
  39.     RandomAccessIterator left_bound = range_begin;
  40.     RandomAccessIterator right_bound = range_end;
  41.     while (left_bound + 1 < right_bound) {
  42.         size_t size_one_third = (right_bound - left_bound) / 3; // размер 2-х поддиапазонов
  43.         const RandomAccessIterator middle_left = left_bound + size_one_third;
  44.         const RandomAccessIterator middle_right = right_bound - left_bound < 3 ? right_bound - 1 : middle_left + size_one_third;
  45.        
  46.         future<bool> is_first_one_third = async([middle_left, &value] {
  47.             return !(*middle_left < value); }); // false - левая часть нас не интересует
  48.         bool is_second_one_third = !(*middle_right < value);
  49.        
  50.         if (is_first_one_third.get()) {
  51.             right_bound = middle_left;
  52.         } else if (is_second_one_third) {
  53.             left_bound = middle_left;
  54.             right_bound = middle_right;
  55.         } else {
  56.             left_bound = middle_right;
  57.         }
  58.     }
  59.     if (left_bound == range_begin && !(*left_bound < value)) {
  60.         return left_bound;
  61.     } else {
  62.         return right_bound;
  63.     }
  64. }
  65.  
  66.  
  67. /* АВТОРСКОЕ РЕШЕНИЕ */
  68. //template <typename RandomAccessIterator, typename Value>
  69. //RandomAccessIterator LowerBound(const execution::parallel_policy&, RandomAccessIterator range_begin, RandomAccessIterator range_end, const Value& value) {
  70. //    auto left_bound = range_begin;
  71. //    auto right_bound = range_end;
  72. //    while (left_bound + 1 < right_bound) {
  73. //        const int distance = right_bound - left_bound;
  74. //        const int part_length = max(1, distance / 3);
  75. //        const auto middle_left = left_bound + part_length;
  76. //        const auto middle_right = right_bound - part_length;
  77. //
  78. //        auto left_less_future = async([middle_left, &value] { return *middle_left < value; });
  79. //
  80. //        if (*middle_right < value) {
  81. //            left_bound = middle_right;
  82. //        } else if (left_less_future.get()) {
  83. //            left_bound = middle_left;
  84. //            right_bound = middle_right;
  85. //        } else {
  86. //            right_bound = middle_left;
  87. //        }
  88. //    }
  89. //    if (left_bound == range_begin && !(*left_bound < value)) {
  90. //        return left_bound;
  91. //    } else {
  92. //        return right_bound;
  93. //    }
  94. //}
  95.  
  96.  
  97. /* МЕДЛЕННОЕ РЕШЕНИЕ */
  98. //template <typename RandomAccessIterator, typename Value>
  99. //RandomAccessIterator LowerBound(const execution::parallel_policy&, RandomAccessIterator range_begin,
  100. //    RandomAccessIterator range_end, const Value& value) {
  101. //    if (range_end - range_begin == 1) {
  102. //        return range_begin;
  103. //    }
  104. //    if (range_end - range_begin == 2) {
  105. //        return *range_begin < value ? range_begin : range_end;
  106. //    }
  107. //    // размер 2-х поддиапазонов
  108. //    size_t size_one_third = (range_end - range_begin) / 3;
  109. //    const RandomAccessIterator middle_left = range_begin + size_one_third;
  110. //    const RandomAccessIterator middle_right = middle_left + size_one_third;
  111. //    future<bool> is_first_one_third = async([middle_left, &value] {
  112. //        return !(*middle_left < value); }); // false - левая часть нас не интересует
  113. //    bool is_second_one_third = !(*middle_right < value);
  114. //    //future<bool> no_is_second_one_third = async([middle_right, &value] {
  115. //    //    return *middle_left < value; });
  116. //
  117. //    if (is_first_one_third.get()) {
  118. //        return LowerBound(range_begin, middle_left, value);
  119. //    } else if (is_second_one_third) {
  120. //        return LowerBound(middle_left, middle_right, value);
  121. //    } else {
  122. //        return LowerBound(middle_right, range_end, value);
  123. //    }
  124. //}
  125.  
  126. int main() {
  127.     const vector<string> strings = { "cat", "dog", "dog", "horse" };
  128.  
  129.     const vector<string> requests = { "bear", "cat", "deer", "dog", "dogs", "horses" };
  130.  
  131.     // последовательные версии
  132.     cout << "Request [" << requests[0] << "] -> position "
  133.         << LowerBound(strings.begin(), strings.end(), requests[0]) - strings.begin() << endl;
  134.     cout << "Request [" << requests[1] << "] -> position "
  135.         << LowerBound(execution::seq, strings.begin(), strings.end(), requests[1])
  136.         - strings.begin()
  137.         << endl;
  138.     cout << "Request [" << requests[2] << "] -> position "
  139.         << LowerBound(execution::seq, strings.begin(), strings.end(), requests[2])
  140.         - strings.begin()
  141.         << endl;
  142.  
  143.     // параллельные
  144.     cout << "Request [" << requests[3] << "] -> position "
  145.         << LowerBound(execution::par, strings.begin(), strings.end(), requests[3])
  146.         - strings.begin()
  147.         << endl;
  148.     cout << "Request [" << requests[4] << "] -> position "
  149.         << LowerBound(execution::par, strings.begin(), strings.end(), requests[4])
  150.         - strings.begin()
  151.         << endl;
  152.     cout << "Request [" << requests[5] << "] -> position "
  153.         << LowerBound(execution::par, strings.begin(), strings.end(), requests[5])
  154.         - strings.begin()
  155.         << endl;
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement