【问题标题】: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];
}

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

如何简化功能?

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

【问题讨论】:

    标签: c++ algorithm sorting quicksort


    【解决方案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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多