【问题标题】:How to find the first smaller element than an integer X in a vector ? (c++)如何在向量中找到第一个小于整数 X 的元素? (c++)
【发布时间】:2012-11-04 03:42:27
【问题描述】:

如果我有以下向量 {10 10 10 20 20 20 30 30} 我想要一个函数返回整数的位置 = X 或直接返回 X 之后的较小元素,例如,如果我正在搜索 11 我希望函数返回 2 因为第二个元素(10)是第一个较小的元素向量中的元素超过 11。
我尝试使用 lower_bound,但这不起作用。

int myints[] = {10,20,30,30,20,10,10,20};
vector<int> v(myints,myints+8);           // 10 20 30 30 20 10 10 20
vector<int>::iterator low,up;

sort (v.begin(), v.end());                // 10 10 10 20 20 20 30 30

low=lower_bound (v.begin(), v.end(), 11); //
up= upper_bound (v.begin(), v.end(), 11); //

cout << "lower_bound at position " << int(low- v.begin()) << endl;
cout << "upper_bound at position " << int(up - v.begin()) << endl;

return 0;

此代码输出:

lower_bound at position 3
upper_bound at position 3

【问题讨论】:

  • 但在您的示例中,位置 2 不是小于 11 的第一个元素。它的 last 元素更小。可能是upper_bound() - 1,但实际上你需要明确你想要什么并适当地编码。
  • 你的向量总是排序的吗?还是只是巧合?

标签: c++ stl vector binary-search


【解决方案1】:

cppreference 告诉我std::lower_bound

返回一个迭代器,该迭代器指向范围 [first, last) 中不小于值

的第一个元素

std::upper_bound

返回一个迭代器,该迭代器指向范围 [first, last) 中大于值

的第一个元素

在这种情况下,给定一个包含 10 10 10 20 20 20 30 30 的向量,我希望这两个函数都指向第一个 20,它位于向量中的第 3 位,并且确实是您两次得到的结果。如果您改为要求20std::lower_bound 将返回一个迭代器,该迭代器指向向量中的第一个 20(位置 3)...第一个数字不少于 20,并且您会得到相同的结果要求11。但在这种情况下,std::upper_bound 将返回一个指向第一个 30(位置 6)的迭代器,这是第一个大于 20 的值。

只需将迭代器移回一个即可获得小于目标数的最后一个值,std::prev 是一种方法。

【讨论】:

    【解决方案2】:

    嗯,upper_bound 返回大于测试项的第一个项目,那么之前的那个(如果存在的话)就是你想要的那个?

    【讨论】:

    • 我认为可以解决它.. 一个小问题,为什么 lower_bound 在这里返回 20?
    • @LoersAntario 请参阅我在回答中引用的lower_bound 的文档;-)
    【解决方案3】:

    你可以这样做...如果向量为空,最好返回一个迭代器...

    auto find_next_smaller(vector<int> vec, const int x) { 
        std::sort(vec.begin(), vec.end());
        auto it = std::lower_bound(vec.begin(), vec.end(), x); 
        if (it == vec.end()) { 
          it = (vec.rbegin()+1).base();
        }
        else if (it != vec.begin() && *it > x) { 
            --it; 
        }
    
        return it; 
    } 
    

    【讨论】:

      【解决方案4】:

      如果必须找到一个小于或等于某个 x 的元素,那么可以使用 multiset 来做到这一点。

      #include <iostream> 
      #include <set> 
      #include <iterator> 
      
      using namespace std; 
      
      int main() 
      {
          multiset <int, greater <int> > iammultiset;
          iammultiset.insert(10);
          iammultiset.insert(10);
          iammultiset.insert(14);
          iammultiset.insert(20);
          iammultiset.insert(20);
          iammultiset.insert(30);
          iammultiset.insert(40);
          iammultiset.insert(50);
          //{10,10,14,20,20,30,40,50}
          
          cout<<*iammultiset.lower_bound(17) << endl;
          //The Output here will be 14.
          
          cout<<*iammultiset.lower_bound(20) << endl;
          //The Output here will be 20.
      }
      

      【讨论】:

        猜你喜欢
        • 2019-11-06
        • 2014-05-21
        • 1970-01-01
        • 1970-01-01
        • 2016-11-09
        • 1970-01-01
        • 2017-10-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多