Проверить массив с помощью std :: is_sorted, но с заданной точностью

Все это в названии.

Рассмотрим следующий код:

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

using namespace std;

int main(){
 const int n=12;
 ****** x[n];

 x[0]=-0.717778;
 x[1]=-0.496843;
 x[2]=-0.429063;
 x[3]=-0.3596;
 x[4]=-0.205607;
 x[5]=0.0730536;
 x[6]=0.138018;
 x[7]=0.585526;
 x[8]=2.40104;
 x[9]=3.752680001; //here
 x[10]=3.75268;
 x[11]=4.55704;

 std::cout << std::is_sorted(x,x+n) << std::endl;

}
</typeinfo></vector></algorithm></iostream>

в принципе, я бы хотел, чтобы он возвращал 1 (для true): хотя я вижу, что x[9] больше, чем x[10], разница между ними меньше 1e-8 поэтому я считаю их равными.

2 ответа

Я не верю, что есть стандартный алгоритм библиотеки, который будет делать это точно, но std::is_sorted_until поможет.

bool sorted = true;
auto b = std::begin(x), e = std::end(x);
while (true)
{
 b = std::is_sorted_until(b,e);
 if (b == e)
 break;
 if (b[-1] - b[0] > epsilon)
 {
 sorted = false;
 break;
 }
}

Хотя это может быть просто чрезмерным. Может быть, простой цикл без стандартных алгоритмов будет проще.

bool sorted = true;
auto b = std::begin(x), e = std::end(x) - 1;
while (b < e)
{
 if (b[0] - b[1] > epsilon)
 {
 sorted = false;
 break;
 }
 ++b;
}

Да, это проще.


Я бы использовал (С++ 14):

std::adjacent_find(
 std::begin(x),
 std::end(x),
 [epsilon](const auto& lhs, const auto& rhs) { return lhs > rhs + epsilon;})
 == std::end(x);

as is_sorted будет вводить в заблуждение.

или в С++ 11:

std::adjacent_find(
 std::begin(x),
 std::end(x),
 [epsilon](const ******& lhs, const ******& rhs) { return lhs > rhs + epsilon;})
 == std::end(x);

licensed under cc by-sa 3.0 with attribution.