有没有办法避免使用全局变量来实现qsort

时间:2017-09-26 01:41:41

标签: c++ qsort

我的项目包含一个.h文件和多个.cpp文件。头文件包含当前实现排序的名称空间UF u seful f 修订的缩写)。

这是通过在UF.cpp中定义比较器来完成的:

    int compar_int_asc(const void *a, const void *b)
    {
        int aa = *((int *)a), bb = *((int *)b);
        if (base_arr_int[aa] < base_arr_int[bb])
            return -1;
        if (base_arr_int[aa] == base_arr_int[bb])
            return 0;
        if (base_arr_int[aa] > base_arr_int[bb])
            return 1;
    }

目前,需要由base_arr_int访问的基本数组qsort和上面的比较函数在main.cpp中声明,并在UF.cpp中表示。

我在另一个类qsort中访问SEP,如下所示。首先,在SEP.cpp,我是extern base_arr_int。然后,如果ratios[100]SEP的原生和本地整数数组,我会在SEP.cpp内执行以下操作。

base_arr_int = ratios;
qsort(indices, 100, sizeof(int), UF::compar_int_asc);

这是使用多个类实现qsort的最佳方法吗?

特别是,我希望尽可能避免使用main.cpp中定义的全局变量。有没有替代设计?

1 个答案:

答案 0 :(得分:1)

全局变量的目的是以图形方式将数组放在自定义比较器中。为了消除全局变量,让我们将ratio放入自定义比较器中。为此,自定义比较器不能是普通函数或函数指针。它必须是功能对象。并std::sort支持。

让我们一步一步来做。

所以,你有一个存储东西的数组。

int ratio[5] = {300, 400, 200, 500, 100};

但你不想直接对它进行排序。您创建一个实际排序的indice数组。

int indice[5] = {0, 1, 2, 3, 4};

目标是对indice进行排序。让我们写一下:

std::sort(indice, indice + 5);

但它不是你想要的。您还需要传递自定义比较器index_comp,因为默认的小于比较器不是您需要的。

std::sort(indice, indice + 5, index_comp);

其余的工作是如何写index_comp。它实际上很简单:lambda表达式

auto index_comp = [&ratio](int index_left, int index_right) { return ratio[index_left] < ratio[index_right]; };

此lambda表达式通过引用(ratio)捕获数组[&ratio]。它有一个参数列表,有两个指标。正文比较ratio中的两个实际对象。

如果您更喜欢旧学校的方式,lambda表达式只是以下语法糖:

class Compiler_Generated_Name
{
private:
    int (&ratio)[5];

public:
    Compiler_Generated_Name(int (&ratio_)[5]) : ratio(ratio_) {}

    bool operator()(int index_left, int index_right)
    {
        return ratio[index_left] < ratio[index_right];
    }
};

Compiler_Generated_Name index_comp(ratio);

整个代码:

#include <iostream>
#include <algorithm>

int main()
{
    int ratio[5] = {300, 400, 200, 500, 100};
    int indice[5] = {0, 1, 2, 3, 4};

    auto index_comp = [&ratio](int index_left, int index_right) { return ratio[index_left] < ratio[index_right]; };

    std::sort(indice, indice + 5, index_comp);

    for (int i = 0; i < 5; ++i)
        std::cout << ratio[indice[i]] << ' ';
}