有没有办法避免使用全局变量来实现 qsort
Is there a way to avoid having global variable to implement qsort
我有一个包含单个 .h
文件和多个 .cpp
文件的项目。头文件包含当前实现排序的命名空间UF
(useful functions 的缩写
这是通过在 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;
}
目前qsort
需要访问的基础数组base_arr_int
和上面的比较器函数在main.cpp
声明,在UF.cpp
外部声明。
我在不同的 class、SEP
中访问 qsort
,如下所示。首先,在 SEP.cpp
中,我 extern base_arr_int
。然后,如果 ratios[100]
是 SEP
本地的整数数组,我在 SEP.cpp
.
中执行以下操作
base_arr_int = ratios;
qsort(indices, 100, sizeof(int), UF::compar_int_asc);
这是使用多个 classes 实现 qsort 的最佳方式吗?
特别是,我想尽可能避免使用main.cpp
中定义的全局变量。有没有其他设计?
全局变量的作用是象征性地将数组放置在自定义比较器中。为了消除全局变量,让我们直接将 ratio
放入自定义比较器中。为此,自定义比较器不能是普通函数或函数指针。它需要是一个 函数对象 。 std::sort
支持。
让我们一步步来吧。
所以,你有一个存储东西的数组。
int ratio[5] = {300, 400, 200, 500, 100};
但你不想直接排序。您创建了一个实际排序的索引数组。
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]] << ' ';
}
我有一个包含单个 .h
文件和多个 .cpp
文件的项目。头文件包含当前实现排序的命名空间UF
(useful functions 的缩写
这是通过在 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;
}
目前qsort
需要访问的基础数组base_arr_int
和上面的比较器函数在main.cpp
声明,在UF.cpp
外部声明。
我在不同的 class、SEP
中访问 qsort
,如下所示。首先,在 SEP.cpp
中,我 extern base_arr_int
。然后,如果 ratios[100]
是 SEP
本地的整数数组,我在 SEP.cpp
.
base_arr_int = ratios;
qsort(indices, 100, sizeof(int), UF::compar_int_asc);
这是使用多个 classes 实现 qsort 的最佳方式吗?
特别是,我想尽可能避免使用main.cpp
中定义的全局变量。有没有其他设计?
全局变量的作用是象征性地将数组放置在自定义比较器中。为了消除全局变量,让我们直接将 ratio
放入自定义比较器中。为此,自定义比较器不能是普通函数或函数指针。它需要是一个 函数对象 。 std::sort
支持。
让我们一步步来吧。
所以,你有一个存储东西的数组。
int ratio[5] = {300, 400, 200, 500, 100};
但你不想直接排序。您创建了一个实际排序的索引数组。
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]] << ' ';
}