我正在开发一个C++应用程序.
我有2个点向量
vector<Point2f> vectorAll;
vector<Point2f> vectorSpecial;
Run Code Online (Sandbox Code Playgroud)
Point2f已定义 typedef Point_<float> Point2f;
vectorAll有1000点而vectorSpecial有10点.
第一步:
我需要根据vectorAll中的顺序对vectorSpecial中的点进行排序.所以像这样:
For each Point in vectorSpecial
Get The Order Of that point in the vectorAll
Insert it in the correct order in a new vector
Run Code Online (Sandbox Code Playgroud)
我可以做一个双循环并保存索引.然后根据索引对点进行排序.然而,当我们有很多点时,这种方法花费的时间太长(例如,vectorAll中的10000个点和vectorSpecial中的1000个点,因此千万次迭代)
有什么更好的方法呢?
第二步:
vectorApecial中的某些点可能在vectorAll中不可用.我需要采取最接近它的点(通过使用通常的距离公式sqrt((x1-x2)^2 + (y1-y2)^2))
这也可以在循环时完成,但如果有人对更好的方法有任何建议,我将不胜感激.
非常感谢您的帮助
如果我想计算从a中检索到的一堆数字的总和std::istream,我可以执行以下操作:
// std::istream & is = ...
int total = std::accumulate(std::istream_iterator<int>(is),
std::istream_iterator<int>(),
0);
Run Code Online (Sandbox Code Playgroud)
但是,如果我想计算它们的平均值,我需要累积两个不同的结果:
std::accumulate)std::distance)有没有办法"合并"这两种算法并在迭代器范围的单次传递中"并排"运行它们?我想做的事情如下:
using std::placeholders;
int total, count;
std::tie(total, count) = merge_somehow(std::istream_iterator<int>(is),
std::istream_iterator<int>(),
std::bind(std::accumulate, _1, _2, 0),
std::distance);
double average = (double)total / count;
Run Code Online (Sandbox Code Playgroud)
这可能吗?
我正在尝试对此进行相反的操作:
std::ostream outs; // properly initialized of course
std::set<int> my_set; // ditto
outs << my_set.size();
std::copy( my_set.begin(), my_set.end(), std::ostream_iterator<int>( outs ) );
Run Code Online (Sandbox Code Playgroud)
它应该是这样的:
std::istream ins;
std::set<int>::size_type size;
ins >> size;
std::copy( std::istream_iterator<int>( ins ), std::istream_iterator<int>( ins ) ???, std::inserter( my_set, my_set.end() ) );
Run Code Online (Sandbox Code Playgroud)
但是我坚持使用'end'迭代器 - 输入交互器不能使用std :: advance,我也不能使用两个具有相同源的流...
有什么优雅的方法如何解决这个问题?当然我可以用于循环,但也许有更好的东西:)
tl; dr:是否可以有效地在双向链表上实现快速排序?在考虑之前我的理解是,不,不是.
前几天我有机会考虑基本排序算法的迭代器要求.基本的O(N²)非常简单.
快速排序
std :: sort中的introsort_loop(如在gnu标准库/ hp(1994)/ silicon graphics(1996)中)要求它是random_access.
__introsort_loop(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Size __depth_limit, _Compare __comp)
Run Code Online (Sandbox Code Playgroud)
正如我所期待的那样.
现在经过仔细检查,我无法找到真正的理由要求快速排序.唯一明确要求random_access_iterators的是std::__median需要计算中间元素的调用.常规的香草快速排序不计算中位数.
分区包括一个检查
if (!(__first < __last))
return __first;
Run Code Online (Sandbox Code Playgroud)
对双向传输并不是一个有用的检查.但是,应该可以通过检查前一个分区行程(从左到右/从右到左)来替换它,条件是简单
if ( __first == __last ) this_partitioning_is_done = true;
Run Code Online (Sandbox Code Playgroud)
是否可以仅使用双向迭代器相当有效地实现快速排序?递归深度仍然可以保护.
NB.我还没有尝试过实际的实现.
我在N3485 25.3.1 [alg.copy]中查看了C++标准,它定义了4种算法:
copycopy_backwardcopy_ifcopy_n在描述中copy,有这个注释25.3.1 [alg.copy]/3:
要求:结果不应在[first,last]范围内
也就是说,copy当范围重叠(类似于memcpy)时,并不总是正常工作.
copy_backward并且copy_if有类似的语言禁止重叠范围(分别为25.3.1 [alg.copy]/14和25.3.1 [alg.copy]/8).
但是,没有这样的禁令copy_n,也没有copy_n_backward.这是否意味着copy_n当范围重叠时做正确的事情?
(MSVC++的实现copy_n似乎委托给了std::memmove,所以我知道它在MSVC++ 2013上是安全的.但是如果标准暗示的话,我不想依赖它)
我有一个名为Graph的C++类,它有一个算法方法for_each_node().我可以把它变成一个模板,像这样:
template <class UnaryFunction>
UnaryFunction Graph::for_each_node (UnaryFunction f)
{
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
或者使用std :: function,如下所示:
typedef std::function<void (Node&)> ForEachNodeFunc;
ForEachNodeFunc Graph::for_each_node (ForEachNodeFunc f)
{
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
标准算法,例如std :: for_each,使用第一种方法,而一些库,例如gtkmm(它是GTK +的C++绑定),将函数作为包含它们的对象的函数指针.
每个选项有哪些优点和缺点?我不知道该选哪个.应该影响选择的是什么:我的Graph类是一个类模板,或者算法方法或速度要求预计会使用多少个不同的函数?
为什么_n版本的copy,fill并且generate已经在C++ 11中提供了,为什么只有这些算法呢?
为什么有些STL算法提供了额外的'_if'功能而不是重载它?
// example:
find(beg, end, val);
find_if(beg, end, pred);
Run Code Online (Sandbox Code Playgroud)
难道他们只是重载这些算法而不是制作额外的_if功能吗?
我有一个可以简化为基本的并行代码:
#include <algorithm>
#include <vector>
struct TKeyObjPtr;
class TObj
{
public:
virtual void Calculate(TKeyObjPtr const &) = 0;
};
struct TKeyObjPtr
{
int Key;
TObj *ObjPtr;
};
void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec)
{
#pragma omp parallel for
for (auto It1= KeyObjPtrVec.begin(); It1!=KeyObjPtrVec.end(); ++It1)
for (auto It2= It1+1; It2!=KeyObjPtrVec.end() && It2->Key==It1->Key; ++It2)
It1->ObjPtr->Calculate(*It2);
}
Run Code Online (Sandbox Code Playgroud)
我想通过使用c ++ 17并行算法来实现代码的现代化.不幸的是,我在重写这么简单的代码时遇到了麻烦.
一个选项将使用boost::counting_iterator:
void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec)
{
std::for_each(std::execution::par_unseq,
boost::counting_iterator<std::size_t>(0u),
boost::counting_iterator<std::size_t>(KeyObjPtrVec.size()),
[&KeyObjPtrVec](auto i)
{
for (auto j= i+1; j<KeyObjPtrVec.size() && KeyObjPtrVec[j].Key==KeyObjPtrVec[i].Key; ++j)
KeyObjPtrVec[i].ObjPtr->Calculate(KeyObjPtrVec[j]); …Run Code Online (Sandbox Code Playgroud) stl-algorithm ×10
c++ ×9
algorithm ×4
c++11 ×4
iterator ×3
stl ×3
c++17 ×1
msdn ×1
quicksort ×1
sorting ×1
standards ×1
std-function ×1
vector ×1
visual-c++ ×1