C++ 使用std::is_排序,但具有预设精度测试数组
都在标题里 考虑以下代码:C++ 使用std::is_排序,但具有预设精度测试数组,c++,std,C++,Std,都在标题里 考虑以下代码: #include <iostream> #include <algorithm> #include <vector> #include <typeinfo> using namespace std; int main(){ const int n=12; double x[n]; x[0]=-0.717778; x[1]=-0.496843; x[2]=-0.429063;
#include <iostream>
#include <algorithm>
#include <vector>
#include <typeinfo>
using namespace std;
int main(){
const int n=12;
double 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;
}
基本上,我希望它返回1表示真:
虽然我可以看到x[9]比x[10]大,
它们之间的差异小于1e-8
所以我认为它们是相等的。我会使用C++14:
std::adjacent_find(
std::begin(x),
std::end(x),
[epsilon](const auto& lhs, const auto& rhs) { return lhs > rhs + epsilon;})
== std::end(x);
照目前的情况,这将是一种误导
或者在C++11中:
std::adjacent_find(
std::begin(x),
std::end(x),
[epsilon](const double& lhs, const double& rhs) { return lhs > rhs + epsilon;})
== std::end(x);
我不相信有一个标准的库算法可以做到这一点,但是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;
}
是的,这更简单。我会使用类似std::nexting_findbeginx,endx,[epsilon]const auto&lhs,const auto&rhs{lhs>rhs+epsilon}==endx的东西。如果你有一个完全相反顺序的序列,但每个元素只比下一个元素大1e-8,会怎么样?你想让它被分类吗?@Jarod42:我听说了,但是如何分类呢?本杰明·林德利:那么我想让它也返回真1!is_sorted just plainly不适用,因为比较没有定义顺序,因为违反了传递性。@Jarod42,相邻的_find解决方案的问题是,它查找彼此相邻的相等元素,但对容器的整体排序(在这种情况下几乎是排序的)没有任何说明。如果第一个元素比第二个元素大到大于ε,这将如何处理?@Niall:它发现元素大于下一个元素,因此证明列表未排序的元素。如果没有这样的元素==std::endx,那么数组将根据OP.@Jarod42进行排序:这将假设第一个或第二个相邻的元素传递到比较器的参数位置。我不认为规范对此做出任何承诺。虽然我可能弄错了,但我面前没有标准。@BenjaminLindley:似乎表明它是这样指定的。。。但是不要。