好的,所以我尝试使用sort来计算项目的向量,这样两个adjecant项目的大小是<= 2d.所以这是我的尝试:
struct item{
long number;
long size;
};
// d is global variable.
bool check(const item& x, const item& y)
{
return ((x.size + y.size) <= (2 * d));
}
// Items is a vector of item.
sort(items.begin(), items.end(), check);
Run Code Online (Sandbox Code Playgroud)
我做错了什么,或者甚至不可能使用这样的条件进行排序?
假设一条线段有25个点,这些点可能分布不均(空间上),如下图所示:

我的问题是我们如何在这 25 个点中选择 10 个点,以便这 10 个点在空间上尽可能均匀分布。在idea的情况下,选择的点应该是这样的:

编辑: 如果我能说出证明“均匀分布”合理的标准,这个问题确实会变得更加优雅。我所知道的是我对所选点的期望:如果我将线段分成 10 个相等的线段。我希望每个小线段上应该有一个点。当然也有可能在一些小的线段中找不到代表点。在这种情况下,我将求助于具有代表点的相邻小线段。下一步我将把选择的相邻段进一步分成两部分:如果每部分都有代表点,那么空代表点问题就解决了。如果我们在其中一个小线段中找不到代表点,我们可以进一步将其分成更小的部分。或者我们可以求助于下一个相邻的线段。
编辑: 使用动态规划,一个可能的解决方案实现如下:
#include <iostream>
#include <vector>
using namespace std;
struct Note
{
int previous_node;
double cost;
};
typedef struct Note Note;
int main()
{
double dis[25] =
{0.0344460805029088, 0.118997681558377, 0.162611735194631,
0.186872604554379, 0.223811939491137, 0.276025076998578,
0.317099480060861, 0.340385726666133, 0.381558457093008,
0.438744359656398, 0.445586200710900, 0.489764395788231,
0.498364051982143, 0.585267750979777, 0.646313010111265,
0.655098003973841, 0.679702676853675, 0.694828622975817,
0.709364830858073, 0.754686681982361, 0.765516788149002,
0.795199901137063, 0.823457828327293, 0.950222048838355, 0.959743958516081};
Note solutions[25];
for(int i=0; i<25; i++)
{
solutions[i].cost = 1000000;
}
solutions[0].cost = 0;
solutions[0].previous_node = …Run Code Online (Sandbox Code Playgroud) 我不明白为什么这段代码会编译:
#include <set>
#include <list>
#include <algorithm>
int modify(int i)
{
return 2*i;
}
int main (int args, char** argv)
{
std::set<int> a;
a.insert(1);
a.insert(2);
a.insert(3);
std::list<int> b; // change to set here
std::transform(a.begin(), a.end(), b.begin(), modify); // line 19
}
Run Code Online (Sandbox Code Playgroud)
同时,如果我只是将 b 的类型从 更改为std::list<int>,std::set<int>它会在编译时(第 19 行)失败并显示错误:read-only variable is not assignmentable。要将 b 用作集合,我需要将变换线更改为
std::transform(a.begin(), a.end(), std::inserter(b, b.begin()), modify);
Run Code Online (Sandbox Code Playgroud)
这是为什么?我以某种方式猜测原因与 set 是一个关联容器而 list 是一个序列容器这一事实有关,但我在这里可能完全偏离了重点。
我忘了提及:我使用默认标准 (c++98) 在 gcc 3.4.2 和 llvm 3.3 上尝试过这个。我使用 c++03 …
我的源代码非常简单:
#include <set>
#include <string>
#include <functional>
#include <algorithm>
#include <iterator>
using namespace std;
void test() {
set<string> *S = new set<string>;
S->insert("hi");
S->insert("lo");
set<string> *T = new set<string>;
T->insert("lo");
set<string> *s = new set<string>;
set<string>::iterator l=s->begin();
set_difference(S->begin(),S->end(),T->begin(),T->end(),l);
}
Run Code Online (Sandbox Code Playgroud)
那么为什么我会收到编译器错误:
c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(4671): error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::basic_string<_Elem,_Traits,_Ax>'
Run Code Online (Sandbox Code Playgroud)
集合"s"只是一组字符串,没有任何常量.
假设一个容器(在这种情况下是一个普通的数组)存储元素
struct Foo
{
char id[8];
// other members
};
Run Code Online (Sandbox Code Playgroud)
现在我想找到一个Fooid以特定字符串开头的id S.由于数组按id排序,我想使用二进制搜索,所以我寻找一个使用与find_if相同的接口执行二进制搜索的函数.在STL中是否有这样的函数,它可以通过使用其他元素来构造algorithm,还是我需要自己实现它.
我正在尝试遵循此处给出的建议,以避免原始循环并std::algorithm改为使用。因此,如果您能在以下情况下帮助我做到这一点,我将不胜感激:
std::stringstream ss;
std::vector<Object> v;
for (const auto& curr : v) { ss << curr.ToString() << '\n'}
return ss.str()
Run Code Online (Sandbox Code Playgroud) 而在C++ STL使用的算法,我发现的类似的方法很多std::merge,std::inplace_merge,std::set_union,std::upper_bound,std::lower-bound等...只需要排序的数据作为输入.
有意义的是,在排序数据上,这些算法会提供更快的结果,但为什么它们也不能处理未排序的数据呢?为什么大多数算法都设计有这样的数据依赖?
鉴于这些类型:
struct ComplexLibraryThing { /*lots of fields*/};
typedef std::map<int, ComplexLibraryThing> MyMap;
struct ShadowComplexLibraryThing { /*Shadow of ComplexLibraryThing*/};
struct MyVecType { int a; ShadowComplexLibraryThing b; };
typedef std::vector<MyVecType> MyVector;
Run Code Online (Sandbox Code Playgroud)
我可以为序列化执行此操作(我的序列化库不支持类似地图的类型):
MyVecType map2pair(std::pair<int, ComplexLibraryThing> const &myPair)
{
MyVecType retVal;
retVal.a = myPair.first;
retVal.b = convertForSerialisation(myPair.second);
return retVal;
}
MyMap myMap = {...};
MyVector myVector;
std::transform(myMap.begin(),
myMap.end(),
std::back_inserter(myVector),
map2pair);
Run Code Online (Sandbox Code Playgroud)
然后,我将向量发送到想要重建 的接收器MyMap。但是,我找不到合适的<algorithm>模板来进行反序列化,如下所示:
MyMap myNewMap;
for (auto const &entry: myVector)
myNewMap[entry.a] = convertForDeserialisation(entry.b);
Run Code Online (Sandbox Code Playgroud)
我该如何使用 来写这个<algorithm>?
(请注意,ComplexLibraryThing地图内的类型不能轻易更改,但我也有一个ShadowComplexLibraryThing …
在 C++14 中,我有一个std::vector值,我想删除与给定值匹配的所有元素,并且我不关心在删除后保留元素的顺序。规范规定std::remove保留剩余元素的相对顺序。
是否有内置算法可以执行类似 a 的操作std::remove,但不保留顺序?我希望这样做,因为将向量末尾的元素交换到要删除的位置的工作量较少,从而打乱向量中元素的顺序。该算法仍然是线性的,因为它必须访问每个元素来检查是否被删除,但如果最终只有少数项目被删除,那么它必须在每个元素上执行的持续工作量就会大大减少。
我得到的错误说fill_n下面的行试图使用已删除的复制构造函数:为什么它不尝试使用移动构造函数?我尝试将它包装在一个std::move但没有帮助.
std::vector< std::thread > workers;
workers.reserve( 10 );
std::fill_n( std::back_inserter( workers ), 10, std::thread( []{ std::cout << "thread\n"; } ) );
Run Code Online (Sandbox Code Playgroud)
但是,如果我将fill_n行更改为
for( int i = 0; i < 10; ++i )
{
workers.push_back( std::thread( []{ std::cout << "thread\n"; } ) );
}
Run Code Online (Sandbox Code Playgroud)
工作正常.我认为这些基本上与我之前从一个到另一个的变化相同,之前有些相似的代码.