【问题标题】:Lower and Upper Bound in case of Decreasing/Non-ascending vector递减/非递增向量的下限和上限
【发布时间】:2021-08-14 17:11:00
【问题描述】:

我理解为递增/递增数组找到的 Lower 和 Upper 的概念。 即

  1. 下界:迭代器指向范围 [first, last) >= Value 中的第一个元素
  2. 上限: 指向范围内第一个元素的迭代器 [first, last) > Value

下面是我面临问题的递减/非递增向量的代码:

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main()
{
    vector<int> vec = {45,40,35,12,6,3};

    auto itr3 = lower_bound(vec.begin(),vec.end(),40);
    auto itr4 = upper_bound(vec.begin(),vec.end(),40);

    if(itr3 == vec.end() && itr4 == vec.end())
        cout<<"Lower & Upper Bound not Found\n";
    else
    {
        cout <<"lower Bound of 40 :"<<*itr3<<endl;
        cout <<"Upper Bound of 40 :"<<*itr4<<endl;
    }

    return 0;
}

输出是:

Lower & Upper Bound not Found.

但如上所述,输出应该是这样的:

lower Bound of 40 :40
Upper Bound of 40 :45

请帮助我理解他在递减/非递增向量的情况下的下限和上限行为。

【问题讨论】:

  • lower_bound()upper_bound() 取决于特定的顺序。默认情况下,数据类型为std::less()。您的向量明确不提供此功能。要么向后使用它(即rbegin()rend()),要么提供反映您选择的顺序的自定义谓词。

标签: c++ algorithm vector lower-bound upperbound


【解决方案1】:

您可以使用反向迭代器来获得 40/45 的结果:

#include <algorithm>
#include <cstdio>
#include <vector>

int main() {
  std::vector<int> const vec = { 45, 40, 35, 12, 6, 3 };

  auto const it_lb = std::lower_bound(vec.rbegin(), vec.rend(), 40);
  auto const it_ub = std::upper_bound(vec.rbegin(), vec.rend(), 40);

  std::printf("Lower: %d\nUpper: %d\n", *it_lb, *it_ub);
}

【讨论】:

    【解决方案2】:

    您需要使用带有比较函数的算法std::lower_boundstd::upper_bound 的另一个重载声明,例如标准函数对象std::greater

    这是一个演示程序。

    #include <iostream>
    #include <functional>
    #include <vector>
    #include <iterator>
    #include <algorithm>
    
    
    int main() 
    {
        std::vector<int> vec = { 45, 40, 35, 12, 6, 3 };
        
        auto lower_bound = std::lower_bound( std::begin( vec ),
                                             std::end( vec ),
                                             40,
                                             std::greater<int>() );
    
        auto upper_bound = std::upper_bound( std::begin( vec ),
                                             std::end( vec ),
                                             40,
                                             std::greater<int>() );
                                             
        std::cout << *lower_bound << " <-> " << *upper_bound << '\n';
        
        return 0;
    }
    

    程序输出是

    40 <-> 35
    

    为了简单起见,我没有检查程序中返回的迭代器是否等于std::end( vec )返回的迭代器。

    您可以使用自己的 lambda 表达式来代替标准函数对象 std::greater。例如

    auto descending = []( const auto &x, const auto &y )
                      {
                        return y < x;
                      };
                      
    auto lower_bound = std::lower_bound( std::begin( vec ),
                                         std::end( vec ),
                                         40,
                                         descending );
    
    auto upper_bound = std::upper_bound( std::begin( vec ),
                                         std::end( vec ),
                                         40,
                                         descending );
    

    【讨论】:

      【解决方案3】:

      std::lower_boundstd::upper_bound 的目标必须是递增(非递减)顺序。

      您可以通过函数的第四个参数指定比较器来更改“增加”的定义。

      您可以使用std::greater 处理降序向量。

      #include<iostream>
      #include<vector>
      #include<algorithm>
      #include<functional>
      
      using namespace std;
      
      int main()
      {
          vector<int> vec = {45,40,35,12,6,3};
      
          auto itr3 = lower_bound(vec.begin(),vec.end(),40,std::greater<int>());
          auto itr4 = upper_bound(vec.begin(),vec.end(),40,std::greater<int>());
      
          if(itr3 == vec.end() && itr4 == vec.end())
              cout<<"Lower & Upper Bound not Found\n";
          else
          {
              cout <<"lower Bound of 40 :"<<*itr3<<endl;
              cout <<"Upper Bound of 40 :"<<*itr4<<endl;
          }
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-28
        • 2012-04-29
        相关资源
        最近更新 更多