带钥匙的普通集装箱

时间:2012-07-22 15:46:16

标签: c++ stl containers

我正在寻找一个容器,它基本上是一个列表,其中每个节点由一个元素和一个元素本身的函数组成(< x,f(x)>)其中x和f(x)是整数。

此容器应允许我以有序的方式插入,其中订单由f(x)提供。 在STL中有类似的东西吗?

3 个答案:

答案 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::mapf(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) == 1f(x)

如果你不能允许这样的重复(即如果你只希望每个first值有一个元素),那么你可以添加一个自定义比较器,只测试每对的{{1}}值