以下函数用于计算std::vector<double>
的中位数。
double vecMed(vector<double>& vec) {
vector<double> copyVec = vec;
sort(copyVec.begin(), copyVec.end());
if( copyVec.size()%2 == 0)
return (copyVec[floor(static_cast<double>(copyVec.size())/2.0)] + copyVec[ceil(static_cast<double>(copyVec.size())/2.0)]) / 2.0;
else
return copyVec[copyVec.size()/2];
}
我在这条线上遇到了一个段错误,有时候:
return (copyVec[floor(static_cast<double>(copyVec.size())/2.0)] + copyVec[ceil(static_cast<double>(copyVec.size())/2.0)]) / 2.0;
有人能看到这个功能有问题吗?
段错误可能是由于我不知道的其他地方的内存损坏,但我想确保在我探索这种可能性之前,我没有在上面的代码中犯一个微妙或粗心的错误。 / p>
GDB说:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000428ab6 in vecMed (this=0x7fffffffd1b0, vec=...) at ../globals.cpp:834
834 return (copyVec[floor(static_cast<double>(copyVec.size())/2.0)] + copyVec[ceil(static_cast<double>(copyVec.size())/2.0)]) / 2.0;
(gdb) bt
#0 0x0000000000428ab6 in vecMed (this=0x7fffffffd1b0, vec=...) at ../globals.cpp:834
答案 0 :(得分:8)
代码中有太多错误! 我想你想要:
#include <algorithm>
#include <vector>
double vecMed(std::vector<double> vec) {
if(vec.empty()) return 0;
else {
std::sort(vec.begin(), vec.end());
if(vec.size() % 2 == 0)
return (vec[vec.size()/2 - 1] + vec[vec.size()/2]) / 2;
else
return vec[vec.size()/2];
}
}
答案 1 :(得分:4)
首先,如果初始向量为空,那么你所做的并不安全。
其次,在偶数情况下,你的逻辑是不正确的。如果copyVec.size() % 2 == 0
,则为偶数,因此static_cast<double>(copyVec.size())/2.0
是整数。所以地板和ceil都是一样的,所以这可能不是你想要做的。喜欢这样的东西:
const int mid = copyVec.size() / 2;
if (copyVec.size() % 2 == 0) {
return 0.5 * (copyVec[mid] + copyVec[mid+1]); // safe unless size == 0
}
else {
return copyVec[mid]; // e.g. if size == 3, return copyVec[1]
}
答案 2 :(得分:1)
你不需要ceil,你可以使用整数运算更有效地做到这一点:
return (copyVec[copyVec.size()/2] + copyVec[(copyVec.size() + 1)/2]) / 2.0;
现在这段代码将与您的代码相同,但更容易阅读和理解。 首先尝试一些简单的案例和一些边缘案例。在这种情况下,您可能会注意到您的代码无法正确运行空数组。
让我们假设您在调查的代码中没有看到任何可疑内容,您最好的选择是使用调试器。如果您有堆栈损坏,有时使用valgrind也会有所帮助。
您也可以考虑使用std::nth_element
来查找矢量的中位数。