我有
std::vector<double>x={1,2,NAN,3, NAN, 4}
Run Code Online (Sandbox Code Playgroud)
当我尝试x.erase(remove(x.begin(), x.end(), NAN), x.end(),我仍然看到NAN作为
for (auto i:x)
std::cout<<i<<" ";
Run Code Online (Sandbox Code Playgroud)
给
1 2 -nan(ind) 3 -nan(ind) 4
Run Code Online (Sandbox Code Playgroud)
如何删除NAN,所以输出如下?
1 2 3 4
Run Code Online (Sandbox Code Playgroud)
编辑:x是双精度的向量,而不是整数
在IEEE 754浮点的怪异,荒野的世界中,NaN!= NaN。换句话说,两个非数字值彼此不相等。因此,您不能简单地std::remove进行相等性测试。
您需要提供自己的谓词,以调用函数来确定浮点值是否为NaN。如果您的目标是C ++ 11或更高版本,则标准库提供了这样的功能:std::isnan。(如果不是这样,情况就更复杂了。)
将它们放在一起,正确的代码将如下所示:
#include <cmath>
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
std::vector<double> x = {
1,
2,
std::numeric_limits<double>::quiet_NaN(),
3,
std::numeric_limits<double>::quiet_NaN(),
4
};
std::cout << "Before removing: ";
for (auto i : x)
{
std::cout << i << " ";
}
std::cout << "\n";
x.erase(std::remove_if(std::begin(x),
std::end(x),
[](const auto& value) { return std::isnan(value); }),
std::end(x));
std::cout << "After removing: ";
for (auto i : x)
{
std::cout << i << " ";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果它在所有演示代码中迷失了,相关部分就是:
x.erase(std::remove_if(std::begin(x),
std::end(x),
[](const auto& value) { return std::isnan(value); }),
std::end(x));
Run Code Online (Sandbox Code Playgroud)
我将lambda传递给std::remove_if一元谓词。它调用std::isnan,传入值进行检查,然后返回结果,该结果是一个布尔值,指示该值是否为非数字。如果谓词返回true,std::remove_if则执行移除;否则,事实并非如此。
请注意,浮点世界的逻辑通常是NaN值具有传染性。换句话说,任何涉及NaN的操作都将返回NaN作为结果。因此,您尝试删除所有NaN值使我感到有些奇怪。注意不要将它们像不在那里一样推到地毯下面。
| 归档时间: |
|
| 查看次数: |
322 次 |
| 最近记录: |