【问题标题】:Is it possible to filter out the data examined by STL multiset lower_bound using a comparator function?是否可以使用比较器函数过滤掉 STL multiset lower_bound 检查的数据?
【发布时间】:2011-06-23 15:06:47
【问题描述】:

我们使用一个 std::multiset range_type 成员变量来存储我们的 Range 数据。当我们调用

std::multiset<Range>::const_iterator iter = ranges_type.lower_bound(Range(n));
if (iter == ranges_type.end() || iter->low() > n){     
    found = false;
}
else{
    curr = *(iter);
}

ranges_type.lower_bound(Range(n)) 可以返回多个候选 Range 元素。然而,STL multiset::lower_bound(Range(n) 总是选择第一个候选元素。我们想知道是否可以使用比较器函数来控制 ranges_type.lower_type(Range(n)) 返回的候选元素。例如,假设我们只需要 caseNumber 1 或 case Number 10 的 lower_bound 答案。然后我们尝试将类 Range 运算符

bool operator<(const Range& rhs) const{
    if ((mCaseNumber == 10 || mCaseNumber == 1) &&
    (rhs.mCaseNumber == 10 || rhs.mCaseNumber == 1)){
       return mHigh < rhs.mHigh;
     }
     else {
      return false;
     }
}

不幸的是,这个原始运算符不能正常工作。 我们想知道是否可以更改比较器函数,以便 std::lower_bound 仅返回 CaseNumber 10 或 Case 1 的 Range 元素,但不返回 case 15 的 Range 元素。我们的原始类 Range 如下所示。

class Range { 
     public:   
         explicit Range(int item){
            mLow = item;
            mHigh = item;
            mPtr  = 0;
            mMapPtr = 0;
            mStamp = 0;
            mCaseNumber = 100;
            mCurrentN = 0;
         }
         Range(int low, int high, char* ptr = 0,char* mapptr = 0, int stamp = 0, 
               int casenumber = 100, int currN = 0,int currMappedLength = 0){  
            mLow = low;
            mHigh = high;
            mPtr  = ptr;
            mMapPtr = mapptr;
                           mStamp = stamp;
            mCaseNumber = casenumber;
            mCurrentN = currN;
                           mMappedLength = currMappedLength;        
         }
         Range(void){  
            mLow = 0;
            mHigh = 0;
            mPtr  = 0;
            mMapPtr = 0;
                            mStamp = 0;
            mCaseNumber = 100;
            mCurrentN = 0;
         }

         Range(const Range& r):
            mLow(r.mLow),
            mHigh(r.mHigh),
            mPtr(r.mPtr),
            mMapPtr(r.mMapPtr),
            mStamp(r.mStamp),
            mCaseNumber(r.mCaseNumber),
            mCurrentN(r.mCurrentN),
                           mMappedLength(r.mMappedLength)
         {
         }

         ~Range(){
         }  


         bool operator==(const Range& rhs) const{
             return (mLow <= rhs.mLow && mHigh >= rhs.mHigh);
         }
         bool operator<(const Range& rhs) const{
                return mHigh < rhs.mHigh;
         } 
         int low() const { return mLow; }   
         int high() const { return mHigh; }
         char* getPtr() const { return mPtr; }
         char* getMapPtr() const { return mMapPtr; }
         int getStamp() const { return mStamp; }
         int getCaseNumber() const { return mCaseNumber; }
                 int getMappedLength() const { return mMappedLength; }
     private:   
         int mLow;   
         int mHigh; 
         char* mPtr;
         char* mMapPtr;
         int mStamp;
         int mCaseNumber;
         int mCurrentN;
         int mMappedLength;
}; // class Range 

【问题讨论】:

  • 您是否尝试过在构造函数中将指针传递给您的比较器函数?见这里:cplusplus.com/reference/stl/multiset/multiset
  • @Dario_Ramos,是的,我们尝试为 std::lower_bound(ranges_type.begin(),ranges_type.end(),Range(n),Comparator()) 创建一个比较器函数。唉,我们并没有得到正确的答案(即 caseNumber = 10 或 1)。也许,我们的比较函子是错误的。您对比较器函子应该如何有任何想法?我们正在尝试 STL::multiset::equal_range。你认为这会有帮助吗?感谢您的帮助。
  • 我指的是多重集的构造函数,而不是迭代器的构造函数。无论如何,您是否检查过您的 Comparator 函数是否被调用(即调试)?
  • @Dario_Ramos,如果我们将比较函子传递给多重集的构造函数,那么我们最终会忽略上面显示的 Range bool operator
  • @Darip_Ramos,我们检查并发现我们的 Comparator 函数在调试器中被调用。感谢您的帮助。

标签: c++ linux visual-c++ stl


【解决方案1】:

来自std::lower_bound's documentation,作为第三个参数传递的比较函数是:

比较函数对象, 取两个相同类型的值 比范围内的那些, 如果第一个参数返回 true 在第二个参数之前 具体严格弱排序吧 定义,否则为假。

所以,试试这样的:

bool Range::CustomComparator( const Range& lhs, const Range& rhs ){//declare it static
    //Your logic here
}

并将 Range::CustomComparator 传递给 lower_bound 调用

【讨论】:

  • 并确保它仍然是严格的弱排序。
  • @dario_ramos,谢谢您的回答。我们正在尝试 std::equal_range 因为 STL::multiset 多重集有多个 Range 元素候选对应于 Range(n)。您的 lower_bound 比较器将如何处理多个候选人?您是否可以向我们展示自定义比较器仅处理案例编号 1 和 10 而不是案例 15?感谢您的帮助。
  • @Tomalak Geret'kal,感谢您对严格弱排序的回复。这是我们的比较器函数:struct Comparator { int Offset;比较器(int N){ 偏移量 = N; } bool operator () ( const Range& d1, const Range& d2 ) const { if ((d1.getCaseNumber() == 10 || d1.getCaseNumber() == 1 ) && (d2.getCaseNumber() == 10 || d2.getCaseNumber() == 1){ return d1.high() = Offset && d1.high() > Offset) && (d2.low() >= Offset && d2.high() > Offset)); } else return false; } }; 你觉得这样对吗?谢谢。
  • @Frank:对不起,我没有时间为你分析。
  • @dario_ramos,我们刚刚测试了您的 Range::CustomComparator 函数,发现它不能正确处理重叠或重复的范围。这不是由自定义比较器引起的。这是由于 STL lower_bound 严格的弱排序要求造成的。你知道哪种 STL 数据结构和算法最适合处理重叠和重复间隔吗?谢谢
猜你喜欢
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 2016-09-10
  • 1970-01-01
相关资源
最近更新 更多