簡體   English   中英

標准 function 下限未按預期工作?

[英]std function lower bound is not working as expected?

我正在嘗試獲得一種將最接近的值返回到 0.5 的方法,並使用了 std::lower_bound。 為什么這會返回不正確的值,以及一個甚至不在數組中的值? 更糟糕的是,如果我連續多次運行它,它會返回不同的答案。 我能想到的只是它在某種程度上與浮點數和小數點有關,但我無法確定它。 謝謝你的幫助!

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


int test() {


float array[] = {0.730453, 0.699215, 0.669218, 0.637146, 0.604049, 0.572716, 0.541121, 0.50986, 0.47848, 0.449675, 0.419725, 0.3908, 0.363951, 0.338627, 0.312707, 0.289863, 0.26578, 0.244605, 0.224265, 0.204569, 0.185969, 0.169755, 0.155114, 0.140401, 0.126714, 0.115817, 0.104347, 0.0945466, 0.000119226, 9.53812e-05, 9.53812e-05, 7.15359e-05};   
std::vector<float> v(std::begin(array),std::end(array));
std::reverse(std::begin(array),std::end(array));
std::vector<float>::iterator low, up;
low=std::lower_bound (v.begin(), v.end(), 0.5);

std::cout << "lower_bound at position " << (low- v.begin()) << '\n';
std::cout<<"index of thing is "<<low- v.begin()<<endl;
float & element = v[low- v.begin()];
std::cout<<"element closest to 0.5 is "<< element<<endl;
return 0;

            }

您的向量需要為lower_bound進行排序以返回正確的結果。 如果未排序,則調用lower_bound會調用未定義的行為。

所以在調用lower_bound之前,你需要做:

std::sort(v.begin(), v.end());

這是一個演示

似乎array以相反的順序排序。 因此,在構造v之前,您需要反轉array ,而不是之后.:

std::reverse(std::begin(array),std::end(array));  // first reverse
std::vector<float> v(std::begin(array),std::end(array));

那么就不需要對v進行排序了。

此外,您可以使用反向迭代器,而不是反轉arrayv

std::lower_bound (v.rbegin(), v.rend(), 0.5);

或使用不同的謂詞:

std::lower_bound (v.begin(), v.end(), 0.5, std::greater{});

如果您不知道某個范圍內是否已排序,這是一種查找范圍內最接近值的建議方法:

template <typename Iterator>
double closest_to(Iterator begin, Iterator end, double value)
{
    double min_dist = std::numeric_limits<double>::infinity();
    double min_val;
    for(Iterator it = begin; it != end; ++it)
    {
        const double dist = fabs(*it - value);
        if(dist < min_dist)
        {
            min_dist = dist;
            min_val = *it;
        }
    }
    return min_val;
}

然后,像這樣使用它:

std::cout << closest_to(v.begin(), v.end(), 0.5) << std::endl;

如果您知道您的范圍已排序,則使用此實現會更快:

template <typename ForwardIterator>
double closest_to(ForwardIterator begin, ForwardIterator end, double value)
{
  ForwardIterator lb = std::lower_bound(begin, end, value);
  if(lb == begin)
    return *lb;
  Iterator prev = lb - 1;
  if(lb == end)
    return *prev;
  if(value - *prev < *lb - value)
    return *prev;
  else
    return *lb;
}

您的數據需要訂購才能使用lower_bound 默認順序是< ,但您可以指定不同的順序,例如> (通過std::greater )。

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

int test() {

    float array[] = {0.730453, 0.699215, 0.669218, 0.637146, 0.604049, 0.572716, 0.541121, 0.50986, 0.47848, 0.449675, 0.419725, 0.3908, 0.363951, 0.338627, 0.312707, 0.289863, 0.26578, 0.244605, 0.224265, 0.204569, 0.185969, 0.169755, 0.155114, 0.140401, 0.126714, 0.115817, 0.104347, 0.0945466, 0.000119226, 9.53812e-05, 9.53812e-05, 7.15359e-05};   
    std::vector<float> v(std::begin(array),std::end(array));
    std::reverse(std::begin(array),std::end(array));
    std::vector<float>::iterator low, up;
    low=std::lower_bound (v.begin(), v.end(), 0.5, std::greater<float>{});
    
    std::cout << "lower_bound at position " << (low- v.begin()) << '\n';
    std::cout<<"index of thing is "<<low- v.begin()<<std::endl;
    float & element = v[low- v.begin()];
    std::cout<<"element closest to 0.5 is "<< element<<std::endl;
    return 0;

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM