如何简化两个相似的函数

Posted

技术标签:

【中文标题】如何简化两个相似的函数【英文标题】:How to simplify two functions that similar with each other 【发布时间】:2015-05-11 12:50:58 【问题描述】:

我是一名学习计算机工程的学生。 今天我正在学习使用 C++ 进行快速排序。 这是非常棒的算法,我认识到快速排序需要 升序和相反的两个函数。 以下是我的代码!

#include <iostream>
#define ASCENDING 0 
#define DESCENDING 1
#define MAX_SIZE 50001

using namespace std;


int numberCnt;
int sortManner;
int list[MAX_SIZE];

void GetInput();
void QuickSort(int* list, int left, int right, int(*partition)(int*, int, int));
int PartitionAscending(int* list, int left, int right);
int PartitionDescending(int* list, int left, int right);
void Swap(int &a, int &b);

int main()
    GetInput();
    QuickSort(list, 0, numberCnt - 1, sortManner == ASCENDING ? PartitionAscending : PartitionDescending);
    for (int i = 0; i < numberCnt; i++)
        cout << list[i] << endl;
    

    return 0;


void QuickSort(int* list, int left, int right, int (*partition)(int*,int,int))
    if (left < right)
        int pivot = partition(list, left, right);
        QuickSort(list, left, pivot - 1, partition);
        QuickSort(list, pivot + 1, right, partition);
    

int PartitionAscending(int* list, int left, int right)
    int pivotVal = list[left];
    int pivotIdx = left;
    int low = left;
    int high = right + 1;

    do
        do
            low++;
         while (list[low] < pivotVal);
        do
            high--;
         while (list[high] > pivotVal);
        if (low < high)
            Swap(list[low], list[high]);
     while (low < high);

    Swap(list[pivotIdx], list[high]);

    return high;


int PartitionDescending(int* list, int left, int right)
    int pivotVal = list[left];
    int pivotIdx = left;
    int low = left;
    int high = right + 1;

    do
        do
            low++;
         while (list[low] > pivotVal);
        do
            high--;
         while (list[high] < pivotVal);
        if (low < high)
            Swap(list[low], list[high]);
     while (low < high);

    Swap(list[pivotIdx], list[high]);

    return high;


void Swap(int &a, int &b)
    int temp = a;
    a = b;
    b = temp;


void GetInput()
    cin >> numberCnt >> sortManner;
    for (int i = 0; i < numberCnt; i++)
        cin >> list[i];

您知道这些功能彼此非常相似! 这对我来说似乎很浪费!

如何简化功能?

如果你不懂我的泳池英语 请不要犹豫,让我知道:)

【问题讨论】:

【参考方案1】:

您的分区可以采用比较函子,例如:

template <typename Comp>
int Partition(int* list, int left, int right, Comp comp)
    int pivotVal = list[left];
    int pivotIdx = left;
    int low = left;
    int high = right + 1;

    do
        do
            low++;
         while (comp(list[low], pivotVal));
        do
            high--;
         while (!comp(list[high], pivotVal));
        if (low < high)
            Swap(list[low], list[high]);
     while (low < high);

    Swap(list[pivotIdx], list[high]);

    return high;


int PartitionAscending(int* list, int left, int right)
    return Partition(list, left, right, [](int l, int r) return l < r; );
    // or return Partition(list, left, right, std::less<int>());


int PartitionDescending(int* list, int left, int right)
    return Partition(list, left, right, [](int l, int r) return l > r; );
    // or return Partition(list, left, right, std::greater<int>());

【讨论】:

我会将函数简化为这个答案中给出的一个,但也保留 PartitionAscending/PartitionDescending 作为函数本身只是让它们调用具有正确 comp 值的通用 Partition 函数- 使您在调用的代码中立即显而易见 我很抱歉,你刚刚在你的回答中添加了我的观点:)【参考方案2】:

向您的函数添加另一个参数,以指定您是否需要升序或降序调用,布尔值ascending 可以做到这一点,并像这样计算循环条件:

do
   low++;
 while ( ascending ? (list[low] < pivotVal) : (list[low] > pivotVal));

【讨论】:

以上是关于如何简化两个相似的函数的主要内容,如果未能解决你的问题,请参考以下文章

如何捕获相似基因(两个相似哈希算法分析)

计算两个列表之间的相似度

找出两个相似波形之间的时间偏移

如何计算两个文档的相似度

如何衡量两个“任意数据集”间的相似度?

简化 Normals 累积函数的划分