我的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*)}’
我完全不理解这个错误。如何正确声明和实现此比较方法? 谢谢!
答案 0 :(得分:5)
Compare是非静态成员函数,而qsort需要非成员函数(或静态成员函数)。由于您的比较函数似乎不使用该类的任何非静态成员,您可以将其声明为静态。事实上,我不确定你的中值滤波器类是什么。也许你只需要一个命名空间。
为什么不直接对矢量进行排序而不是将其复制到第二个数组中?此外,如果向量具有超过100个元素,则代码将中断。
sort的默认行为只是需要你,但为了完整起见,我展示了如何使用比较函数。
我还更改了函数的返回类型,因为我不明白为什么名为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;
}
}
}
答案 1 :(得分:4)
你不能调用compare,因为它是一个成员函数,需要一个this
指针(即需要在一个对象上调用它)。但是,由于比较函数不需要this
指针,只需将其设为static
函数即可编译。
在你的班级中声明它:
static int compare(const void * a, const void * b);
答案 2 :(得分:2)
与您的问题(您已经得到答案)没有直接关系,但有些意见:
答案 3 :(得分:2)
好的,这更像是Eli Algranti(优秀)答案的附录,而不是对原始问题的答案......请不要忘记忘记;)
这是一个通用代码,用于计算被称为quant
的双向量的分位数x
(下面的代码保留)。
首先要做的事情是:分位数有很多定义(R单独列表9)。下面的代码对应于定义#5(它也是matlab中的默认分位数函数,通常是统计学家在考虑分位数时所考虑的)。
这里的关键思想是,当分位数不落在精确观察上时(例如,当你想要长度为10的数组的15%分位数时),下面的实现实现了(正确的)插值(在这种情况下是相邻分位数之间的10%和20%)。这很重要,因此当你增加观察数量时(这里暗示名称medianfilter
),分位数的值不会突然跳跃而是平滑收敛(这就是为什么这是统计学家的原因&# 39;首选定义)。
代码假定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是偶数时)一次额外调用min()[在本征方言中在向量的最多n / 2个元素上注明.minCoeff()
],即O(n / 2)。
这比使用部分排序(这将花费O(nlog(n / 2)),worst case)或排序(这会花费)要好得多 O(nlogn))