【发布时间】:2012-07-22 15:46:16
【问题描述】:
我正在寻找一个容器,它基本上是一个列表,其中每个节点都由一个元素和元素本身的函数 ( ) 组成,其中 x 和 f(x) 是整数。
这个容器应该允许我以 f(x) 提供顺序的有序方式插入。 STL 中有类似的东西吗?
【问题讨论】:
-
感谢所有答案,无论如何,对于不同的 x 值,我可以获得相同的 f(x) 值。
标签: c++ stl containers
我正在寻找一个容器,它基本上是一个列表,其中每个节点都由一个元素和元素本身的函数 ( ) 组成,其中 x 和 f(x) 是整数。
这个容器应该允许我以 f(x) 提供顺序的有序方式插入。 STL 中有类似的东西吗?
【问题讨论】:
标签: c++ stl containers
您可以使用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)的特性。
【讨论】:
我觉得可以
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) 的计算开销很大,您还可以向比较对象添加一些状态。
【讨论】:
此时,有两个不同的答案建议使用带有自定义比较器的std::set 和将f(x) 映射到x 的std::map。我实际上会选择第三种选择:std::set< std::pair<int,int> >,其中一对是(f(x),x)。
与std::map<> 相比的优势在于,虽然它拥有相同的信息,但它确保x 不会被修改,从而保证迭代地图将始终产生(f(x),x) 对的不变量。与 std::set<int, cmp> 相比,cmp 是 f 的优势在于,该函数只需要计算一次,并且值存在于容器中(这可能会或不会产生影响,具体取决于 f 的成本),另外
这种方法与其他方法的另一个区别(可能是正的或负的)是它自然允许x 的多个值映射到同一个f(x),因为std::pair<> 上的顺序是按字典顺序排列的,容器将存储所有此类对,其顺序首先由f(x) 确定,然后由x 确定x 值与f(x) 相同(即(0,1), (0,3), (1,2) 假设f(1) == f(3) == 0和f(2) == 1。
如果您不能允许此类重复(即,如果您只想为每个 f(x) 值设置一个元素),那么您可以添加一个自定义比较器,该比较器仅测试每对的 first 值。
【讨论】: