【问题标题】:Ordinated Container with key带钥匙的有序容器
【发布时间】:2012-07-22 15:46:16
【问题描述】:

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

这个容器应该允许我以 f(x) 提供顺序的有序方式插入。 STL 中有类似的东西吗?

【问题讨论】:

  • 感谢所有答案,无论如何,对于不同的 x 值,我可以获得相同的 f(x) 值。

标签: c++ stl containers


【解决方案1】:

您可以使用std::mapf(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)的特性。

【讨论】:

    【解决方案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) 的计算开销很大,您还可以向比较对象添加一些状态。

    【讨论】:

      【解决方案3】:

      此时,有两个不同的答案建议使用带有自定义比较器的std::set 和将f(x) 映射到xstd::map。我实际上会选择第三种选择:std::set&lt; std::pair&lt;int,int&gt; &gt;,其中一对是(f(x),x)

      std::map&lt;&gt; 相比的优势在于,虽然它拥有相同的信息,但它确保x 不会被修改,从而保证迭代地图将始终产生(f(x),x) 对的不变量。与 std::set&lt;int, cmp&gt; 相比,cmpf 的优势在于,该函数只需要计算一次,并且值存在于容器中(这可能会或不会产生影响,具体取决于 f 的成本),另外

      这种方法与其他方法的另一个区别(可能是正的或负的)是它自然允许x 的多个值映射到同一个f(x),因为std::pair&lt;&gt; 上的顺序是按字典顺序排列的,容器将存储所有此类对,其顺序首先由f(x) 确定,然后由x 确定x 值与f(x) 相同(即(0,1), (0,3), (1,2) 假设f(1) == f(3) == 0f(2) == 1

      如果您不能允许此类重复(即,如果您只想为每个 f(x) 值设置一个元素),那么您可以添加一个自定义比较器,该比较器仅测试每对的 first 值。

      【讨论】:

        猜你喜欢
        • 2011-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多