推广标准::p艺术到multi_partition
Generalizing std::partition to multi_partition
就像std::p artition根据一元谓词对容器进行分区一样,multi_partition是根据一元谓词对容器进行分区...pred 的顺序与 UnaryPredicates 中列出的顺序相同...,而 false 元素的顺序与 UnaryPredicates 的顺序相同...以及在容器的末尾,并返回所有分区点的列表。 但是我用这个辅助函数没有得到正确的结果:
template <typename ForwardIterator, typename UnaryPredicate, typename... UnaryPredicates>
std::list<ForwardIterator> multi_partition_helper (std::list<ForwardIterator>& partition_points,
ForwardIterator first, ForwardIterator last, UnaryPredicate pred, UnaryPredicates... rest) {
while (true) {
while ((first != last) && pred(*first))
++first;
if (first == last--) break;
while ((first != last) && !pred(*last))
--last;
if (first == last) break;
std::iter_swap (first++, last);
}
partition_points.push_back (first);
multi_partition_helper (partition_points, first, last, rest...);
}
template <typename ForwardIterator, typename UnaryPredicate, typename... UnaryPredicates>
std::list<ForwardIterator> multi_partition_helper (std::list<ForwardIterator>&, ForwardIterator, ForwardIterator) {
// End of recursion.
}
我的做法是不是错了?
一个简单的实现是
template <typename BidirIt, typename... Predicates>
void trivial_mul_part( BidirIt first, BidirIt last, Predicates... preds )
{
std::sort( first, last,
[=] (decltype(*first) const& lhs, decltype(*first) const& rhs)
{
return std::make_tuple(preds(lhs)...) > std::make_tuple(preds(rhs)...);
} );
}
并可用作参考算法。
真正的算法可以根据std::partition
本身递归实现。这个想法是用第 n 个谓词调用 std::partition
,将迭代器获取到 n+1个范围的开头,然后使用此迭代器作为第一个迭代器,将第 n+1个谓词作为谓词进行下一次调用。
template <typename BidirIt, typename OutputIterator>
void multi_partition( BidirIt first, BidirIt last, OutputIterator out ) {}
template <typename BidirIt, typename OutputIterator,
typename Pred, typename... Predicates>
void multi_partition( BidirIt first, BidirIt last, OutputIterator out,
Pred pred, Predicates... preds )
{
auto iter = std::partition(first, last, pred);
*out++ = iter;
multi_partition<BidirIt>(iter, last, out, preds...);
}
作为实际算法,其使用方式如下:
int arr[] {0, 1, 0, 1, 0, 2, 1, 2, 2};
std::vector<int*> iters;
multi_partition(std::begin(arr), std::end(arr), std::back_inserter(iters),
[] (int i) {return i == 2;},
[] (int i) {return i == 1;});
for (auto i : arr)
std::cout << i << ", ";
std::cout << 'n';
for (auto it : iters)
std::cout << "Split at " << it - arr << 'n';
演示。
相关文章:
- 可视化C++:发布模式的运行时库作为'Multi-threaded Debug DLL'
- std::partition segfault issue
- boost beast Websocket Multi Request Server/Client 并不是真正的 mul
- c++如何使用Curl Multi-Interface连续循环
- 在 R 中调用"multi file C++ code with external libraries referenced"
- 适用于Visual Studio 2017的CMake Multi-Project设置
- libcurl进度回调无法与Multi一起使用
- 为什么我不能std :: partition this std :: unordered_map
- 如何使用 std::get 作为 boost-multi-index 容器键的global_fun
- 为什么STD::( multi)集提供非常量迭代方法
- 编译boost时"threading=multi"究竟做了什么
- C++ Multi threading
- C++ Multi-threading?
- Increment a variable string & Multi fstream open c++
- "dynamically allocated memory emulating multi-dimensional array"的正确术语?
- windows c++ multi thread
- std::partition quick sort implementation
- Parallelizing std::nth_element and std::partition
- Visual Studio 字符集 'Not set' vs 'Multi byte character set'
- 从std::partition接收0xcccccccccc指针值意味着什么