C++ C++;-返回向量中小于给定输入的最大元素的最有效方法

C++ C++;-返回向量中小于给定输入的最大元素的最有效方法,c++,vector,stl,C++,Vector,Stl,给定一个未排序的向量和一个相同类型的输入元素,找到向量中小于给定元素的最大元素的最有效方法是什么?这就是我到目前为止所做的: std::vector<double> vec{1,2.2,3.5,4}; double elem = 3; double lessThan(double elem, std::vector<double> vec) { std::vector<double> tmp = vec; tmp.push_back(ele

给定一个未排序的向量和一个相同类型的输入元素,找到向量中小于给定元素的最大元素的最有效方法是什么?这就是我到目前为止所做的:

std::vector<double> vec{1,2.2,3.5,4};
double elem = 3;

double lessThan(double elem, std::vector<double> vec) 
{
    std::vector<double> tmp = vec;
    tmp.push_back(elem);
    sort(tmp.begin(), tmp.end());
    return *(find(tmp.begin(), tmp.end(), elem) - 1);
}

lessThan(elem, vec); //returns 2.2
std::向量向量{1,2.2,3.5,4};
双元素=3;
双lessThan(双元素,标准::向量向量向量)
{
std::vector tmp=vec;
tmp.推回(elem);
排序(tmp.begin(),tmp.end());
return*(find(tmp.begin(),tmp.end(),elem)-1);
}
lessThan(elem,vec)//返回2.2

首先,请不要按值传递向量,因为复制向量会导致值的传递并写入内存,这既昂贵又不必要

接下来,不要
sort()
元素:这既昂贵又不必要。只要做一个线性搜索,记住目前为止找到的最大合适值。您可能可以使用<代码>最大值元素()/代码>,并将大于截止值的元素视为相等类。


我可以编写代码,但我不想破坏你解决家庭作业的乐趣。

最有效的方法是编写你自己的函数。:)例如

#include <iostream>
#include <vector>

std::vector<double>::const_iterator lessThan( const std::vector<double> &v, 
                                              double value ) 
{
    auto first = v.begin();

    while ( first != v.end() && !( *first < value ) ) ++first;

    auto max = first;

    for ( ; first != v.end(); ++first )
    {
        if ( *first < value && *max < *first ) max = first;
    }

    return max;
}

int main() 
{
    std::vector<double> v = { 1, 2.2, 3.5, 4 };
    double value = 3.0;

    auto max = lessThan( v, value );

    if ( max != v.cend() )
    {
        std::cout << "The maximum value less than " << value
                  << " is " << *max << std::endl;
    }

    return 0;
}

感谢@Dietmar Kühl的建议。 我做了这个版本的作业:

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

int main ()
{
   std::vector<double> vec{2.7,1,2.2,3.5,4,2.8,3.0};
   double elem = 3;
   auto it = std::max_element(vec.begin(),vec.end(),
   [elem](const double &x,const double &y)
   {
    if(y<elem & x<y) return true;
    else return false;
   });
   std::cout<<*it<<std::endl;
   return 0;
}
#包括
#包括
#包括
int main()
{
向量向量{2.7,1,2.2,3.5,4,2.8,3.0};
双元素=3;
auto it=std::max_元素(vec.begin(),vec.end(),
[elem](常数双精度&x,常数双精度&y)
{

if(yThanks.I已修改代码以使用max_元素并删除_if,如下所示:
return*max_元素(vec.begin(),remove_if(vec.begin(),vec.end(),[&](double&d){return d>elem;}));
这会更有效吗?@user3294195:它肯定比原来的更有效,但它仍然会遍历范围两次并修改范围。您最好只使用带有适当预测值的
max_element()
,例如类似于
[=](双d0,双d1)的东西{return d0
(我认为这是正确的表达式,但我不完全确定)@user3294195您不能在您的案例中使用std::max_元素。为什么忽略我展示的唯一正确方法?您可能想替换
y@Atomic_alarm这只是一个错误的方法。std::max_元素可能不会在这种情况下使用。@Vlad来自莫斯科,你为什么这么想?@Atomic_报警函数std::max_元素无条件返回一个valid迭代器,即使数组不包含满足要求的元素。例如,尝试查找数组中小于1的元素。@Vlad,来自莫斯科,感谢您的澄清。但是添加一个验证和实现将是正确的。这很有趣。我是唯一一个在代替bla..bla.bla.你完全不知道答案。谢谢莫斯科的@Vlad。我最终使用了这个解决方案,因为它只遍历了一次范围。正如你提到的,我认为max_元素不能使用,除非与另一个函数(如remove_if)结合使用,这需要多次遍历。顺便说一句,如果
value
小于
v
@user3294195中的所有元素,它将中止。请参阅我的代码。检查返回的迭代器是否等于cend()。在这种情况下,这意味着找不到元素。如果
value
小于
v
中的所有元素,是否有方法在返回
min\u元素的函数中合并谓词?我可以添加
如果(value<*min\u元素(v.begin(),v.end())返回min\u元素(v.begin(),v.end())
while
循环之前,但只要值在范围内,就会导致2次遍历。@user3294195我还不明白这个问题,你说的谓词是什么意思?
#include<vector>
#include<iostream>
#include <algorithm> 

int main ()
{
   std::vector<double> vec{2.7,1,2.2,3.5,4,2.8,3.0};
   double elem = 3;
   auto it = std::max_element(vec.begin(),vec.end(),
   [elem](const double &x,const double &y)
   {
    if(y<elem & x<y) return true;
    else return false;
   });
   std::cout<<*it<<std::endl;
   return 0;
}