qsort比较编译错误
qsort comparison compilation error
My medianfilter.cpp类调用qsort
,如下所示。
vector<float> medianfilter::computeMedian(vector<float> v) {
float arr[100];
std::copy(v.begin(), v.end(), arr);
unsigned int i;
qsort(arr, v.size(), sizeof(float), compare);
for (i = 0; i < v.size(); i++) {
printf("%f ", arr[i]);
}
printf("median=%d ", arr[v.size() / 2]);
return v;
}
我比较的实施方式是:
int medianfilter::compare(const void * a, const void * b) {
float fa = *(const float*) a;
float fb = *(const float*) b;
return (fa > fb) - (fa < fb);
}
而mediafilter.hpp中的声明被设置为私有,看起来像这样:
int compare (const void*, const void*);
出现编译错误:cannot convert ‘mediafilter::compare’ from type ‘int (mediafilter::)(const void*, const void*)’ to type ‘__compar_fn_t {aka int (*)(const void*, const void*)}’
我不完全理解这个错误。如何正确声明和实现此比较方法?谢谢
Compare是一个非静态成员函数,而qsort需要一个非成员函数(或静态成员函数)。由于您的compare函数似乎不使用类的任何非静态成员,因此您可以将其声明为静态。事实上,我根本不确定你的中值滤波器类是做什么的。也许您只需要一个名称空间。
为什么不直接对向量进行排序,而不是将其复制到第二个数组中?此外,如果向量包含100个以上的元素,则代码将中断。
默认的排序行为只是希望您需要,但为了完整性,我展示了如何使用比较函数。
我还更改了函数的返回类型,因为我不明白为什么一个名为computeMedian
的函数不会返回中值。。
namespace medianfilter
{
bool compare(float fa, float fb)
{
return fa < fb;
}
float computeMedian(vector<float> v)
{
std::sort(v.begin(), v.end(), compare);
// or simply: std::sort(v.begin(), v.end());
for (size_t i = 0; i < v.size(); i++) {
printf("%f ", v[i]);
}
if (v.empty())
{
// what do you want to happen here?
}
else
{
float median = v[v.size() / 2]; // what should happen if size is odd?
printf("median=%f ", median); // it was %d before
return median;
}
}
}
不能按原样调用compare,因为它是一个成员函数,需要一个this
指针(即需要在对象上调用它)。但是,由于比较函数不需要this
指针,只需将其设置为static
函数,代码就会编译。
在你的类中这样声明:
static int compare(const void * a, const void * b);
与您的问题没有直接关系(您已经有了答案),但有一些观察结果:
- 你对中位数的计算是错误的。如果元素的数量是偶数,则应返回两个中心值的平均值,而不是下一个的值
- 复制到具有设置大小的数组会导致缓冲区溢出。复制到另一个向量并std:对它进行排序,或者(正如@NeilKirk所建议的)只对原始向量进行排序,除非你有理由不修改它
- 没有防止空输入的措施。在这种情况下,中位数是未定义的,但您的实现只会返回arr[0]上发生的任何情况
好吧,这更像是Eli Algranti(优秀)答案的附录,而不是原始问题的答案。
这里有一个通用代码,用于计算称为x
的二重向量的分位数quant
(下面的代码保留该分位数)。
首先:分位数有很多定义(R单独列出9)。下面的代码对应于定义#5(这也是matlab中默认的分位数函数,通常是统计学家在考虑分位数时想到的函数)。
这里的关键思想是,当分位数没有落在精确的观察上时(例如,当你想要长度为10的数组的15%分位数时),下面的实现实现了相邻分位数之间的(正确的)插值(在这种情况下,在10%和20%之间)。这一点很重要,这样当你增加观察次数时(我在这里暗示medianfilter
的名称),分位数的值不会突然跳跃,而是平滑收敛(这就是为什么这是统计学家首选定义的原因之一)。
代码假设x
至少有一个元素(下面的代码是一个较长元素的一部分,我觉得这一点已经提出了)。
不幸的是,它是使用(优秀!)c++特征库中的许多函数编写的,在这个深夜,我翻译特征函数或清理变量名已经太晚了,但关键思想应该是可读的。
#include <Eigen/Dense>
#include <Eigen/QR>
using namespace std;
using namespace Eigen;
using Eigen::MatrixXd;
using Eigen::VectorXd;
using Eigen::VectorXi;
double quantiles(const Ref<const VectorXd>& x,const double quant){
//computes the quantile 'quant' of x.
const int n=x.size();
double lq,uq,fq;
const double q1=n*(double)quant+0.5;
const int index1=floor(q1);
const int index2=ceil(q1);
const double index3=(double)index2-q1;
VectorXd x1=x;
std::nth_element(x1.data(),x1.data()+index1-1,x1.data()+x1.size());
lq=x1(index1-1);
if(index1==index2){
fq=lq;
} else {
uq=x1.segment(index1,x1.size()-index1-1).minCoeff();
fq=lq*index3+uq*(1.0-index3);
}
return(fq);
}
因此,代码使用一个对nth_element的调用,它的平均复杂度为O(n)[对不起,使用大O表示平均值很草率],并且(当n为偶数时)在向量的最多n/2个元素上使用一个额外的对min()的调用[在本征方言中记为.minCoeff()
],即O(n/2)。
这比使用部分排序(最坏情况下会花费O(nlog(n/2))或排序(会花费O(nlogn))
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- std::is_base_of表示ctor编译错误
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- Qt5:使用QCommandLineParser类时出现奇怪的编译错误
- Qt Cmake 错误编译"GuiSupportQt not found"
- Opengl 精度转换错误编译错误 E0415
- 库将ARM架构错误编译为架构X64
- RT 音频 Mac 错误 g++ 编译错误
- 错误编译Boost.log
- 错误编译QT创建者 / QT窗口小部件示例
- 错误编译MIPS32
- Visual Studio 2013 中的错误(编译和运行代码)
- 链接错误编译qt项目在visual 2010
- 无法用模板错误编译nsgmls
- 奇怪的错误.编译失败
- 如果有人调用c++中的方法,则强制错误(编译时)
- 来自autoconf测试的错误编译命令
- 时间限制超出错误C++编译
- SFML 2.3 和 CodeBlocks 错误编译