我正在寻找一个容器,它基本上是一个列表,其中每个节点由一个元素和一个元素本身的函数组成(< x,f(x)>)其中x和f(x)是整数。
此容器应允许我以有序的方式插入,其中订单由f(x)提供。 在STL中有类似的东西吗?
答案 0 :(得分:3)
您可以使用std::map并使用f(x)
作为密钥。
#include <map>
int f(int);
int n = ....;
std::map<int,int> m;
m.insert(std::make_pair(f(n), n));
int i = ...;
m[f(i)] = i;
另一种选择是使用具有合适比较器功能的std::set,如其他答案中所建议的那样。但是,您必须确保比较器实现strict weak ordering,这取决于函数f(int)
的特征。
答案 1 :(得分:2)
我认为你可以
int foo(int x );
struct mycustomcompare {
bool operator() (const int& lhs, const int& rhs) const
{return foo(lhs) < foo(rhs);}
};
int main()
{
std::set<int,mycustomcompare> myset;
myset.insert( 1 );
myset.insert( 2 );
}
当然,如果foo(2)和foo(3)返回相同的值,则只会插入其中一个。如果域存在问题,您可以使用multiset
int foo(int x )
{
return x % 2 ==0;
}
struct mycustomcompare {
bool operator() (const int& lhs, const int& rhs) const
{return foo(lhs) < foo(rhs);}
};
int main()
{
std::multiset<int,mycustomcompare> myset;
myset.insert( 1 );
myset.insert( 2 );
myset.insert( 3);
myset.insert( 4);
myset.insert( 5);
myset.insert( 6);
}
在上面的例子中,所有奇数元素都在集合的前半部分。或者您可以简单地使用向量并使用比较函数进行排序
int foo(int x )
{
return x % 2 ==0;
}
struct mycustomcompare
{
bool operator() (const int& lhs, const int& rhs) const
{return foo(lhs) < foo(rhs);}
};
int main()
{
std::vector<int> myvector;
myvector.push_back( 5);
myvector.push_back( 1 );
myvector.push_back( 6);
myvector.push_back( 2 );
myvector.push_back( 3);
myvector.push_back( 4);
std::sort( myvector.begin() , myvector.end() , mycustomcompare() );
}
如果对f(x)的评估很昂贵,您还可以在比较对象中添加一些状态。
答案 2 :(得分:2)
此时,有两个不同的答案建议使用std::set
自定义比较器和std::map
将f(x)
映射到x
。我实际上会选择第三个选项:std::set< std::pair<int,int> >
,其中对为(f(x),x)
。
std::map<>
的优势在于,虽然它保存相同的信息,但它确保x
不会被修改,从而保证迭代地图上的迭代总是会产生{{{{ 1}}。 (f(x),x)
std::set<int, cmp>
cmp
f
的优势在于函数只需要计算一次,容器中存在该值(可能会产生影响,也可能不产生影响,具体取决于费用为f
),另外还有
这种方法与其他方法(可能是正面的或负面的)的另一个不同之处在于,它自然允许x
的多个值映射到f(x)
,与{std::pair<>
上的顺序相同1}}是词典编纂,容器将按照f(x)
首先确定的顺序存储所有此类对,然后按x
存储x
f(x)
的值(0,1), (0,3), (1,2)
}是相同的(即f(1) == f(3) == 0
假设f(2) == 1
和f(x)
。
如果你不能允许这样的重复(即如果你只希望每个first
值有一个元素),那么你可以添加一个自定义比较器,只测试每对的{{1}}值