代码之家  ›  专栏  ›  技术社区  ›  Steve

不同类型的stl谓词

  •  2
  • Steve  · 技术社区  · 14 年前

    我有一个有序容器类的向量,我需要知道具有给定元素的容器的索引。

    所以,我想做下面的工作,但这显然行不通。我可以创建一个虚拟容器来存放要查找的日期,但我想知道是否有更好的方法。

    struct FooAccDateComp 
    {
      bool operator()(const Container& d1, const MyDate&  f1) const 
      { return   d1->myDate < f1; } 
    };
    
    class Container
    {
       MyDate myDate;
       ...
    };
    
    vector<Container> mystuff; 
    MyDate temp(2008, 3, 15);
    
    //add stuff to variable mystuff
    
    int index = int(upper_bound(events.begin(), events.end(),temp, FooAccDateComp())-events.begin());
    

    编辑:容器类可以包含其他日期。

    4 回复  |  直到 7 年前
        1
  •  4
  •   Mike Seymour    14 年前

    upper_bound 需要能够计算表达式 Comp(date,container) 但是你只提供了 Comp(container,date) . 您需要同时提供:

    struct FooAccDateComp 
    {
        bool operator()(const Container& c, const MyDate& d) const 
            { return c.myDate < d; } 
    
        bool operator()(const MyDate& d, const Container& c) const 
            { return d < c.myDate; } 
    };
    

    记住,矢量必须根据以下比较进行排序: 上界 和朋友一起工作。

        2
  •  1
  •   Maxim Egorushkin    14 年前

    您不一定需要特殊的谓词,只需启用容器和mydate之间的比较即可。

    #include <vector>
    
    struct MyDate {
       MyDate(int, int, int);
    };
    
    struct Container {
       MyDate myDate;
    };
    
    // enable comparison between Container and MyDate
    bool operator<(Container const&, MyDate const&);
    bool operator==(Container const&, MyDate const&);
    
    std::vector<Container> v; 
    //add stuff to variable mystuff
    MyDate temp(2008, 3, 15);
    std::vector<Container>::iterator i = std::lower_bound(v.begin(), v.end(), temp);
    ptrdiff_t index = i != v.end() && *i == temp ? i - v.begin() : -1;
    
        3
  •  0
  •   a1ex07    14 年前

    你可以使用 find_if 如果你不介意降低性能(你说你有一个排序向量 Container ,所以二进制搜索会更快) 或者你可以添加

    struct Container {
        MyDate myDate;
        operator MyDate () {return myDate}; 
    }
    bool operator <(MyDate  const&, MyDate const&)
    {
      return // your logic here
    };    
    

    现在您可以使用二进制搜索函数

    std::vector<Container>::iterator i = std::upper_bound(v.begin(), v.end(), MyDateObject);

    当然,只有向量按 Container.myDate

        4
  •  0
  •   Marc van Leeuwen    7 年前

    您的示例以几种简单的方式被破坏:类 Container 应在之前定义 FooAccDateComp 为了在那里使用,你应该 myDate 公众的 成员 集装箱 ,在比较方法中使用 .myDate 而不是 ->myDate 最后决定是否调用向量 mystuff events 但不能两者混合。我想已经做了适当的修正。

    您应该定义比较函数 Date 作为第一个参数的参数和 集装箱 参数为秒;与您所做的相反。或者你可以用 std::lower_bound 而不是 std::upper_bound 如果这适合你的目的(因为你不说你要做什么 index 很难说),因为问题中所做的选择已经适应了这一点。与当前接受的答案相反,如果您只使用 标准::上限 或仅 标准::下限 (尽管如果使用 std::equal_range 或同时使用 标准::上限 标准::下限 )

    您可以在标准中一眼就发现这些有点奇怪的规格,但是有一种方法可以理解,而不必查找为什么它们必须是这样的。使用时 lower_bound ,您要找到分隔 集装箱 (严格地)少于你给出的条目 日期 从那些不是的,这需要调用比较函数 日期 第二个位置的参数。如果你要求 upper_bound (正如您所做的那样),您希望找到一个点来分隔不严格的条目 更大的 比你给的 日期 这就需要调用比较函数 日期 第一个位置的参数(并对返回的布尔结果求反)。为了 equal_range 你当然需要两种可能性。