按相反顺序排序。 "Don't repeat yourself"规则

Sort in reverse order. "Don't repeat yourself" rule

本文关键字:repeat 规则 yourself Don 顺序 排序      更新时间:2023-10-16

下面是一段执行插入排序的c++代码:

#ifndef INSERTIONSORT
#define INSERTIONSORT
template<class T> 
void insertionSort(T* elements, int size, int reverse = 0) {
    T tempElement;
    int j;
    for (int i = 0; i < size; ++i) {
        tempElement = elements[i];
        for (j = i - 1; j >= 0 && elements[j] > tempElement; j--)
            elements[j + 1] = elements[j];
        elements[j + 1] = tempElement;
    }
}
#endif

如果不重复代码我就写不出来。这不是我第一次遇到这种问题了。我只需要把<替换成>,当reverse = 1时。我尝试的第一种方法是使用三元操作符:

(repeat)?(elements[j] > tempElement):(elements[j] < tempElement)

它看起来有点奇怪,我知道这不是解决问题的最好方法,所以我试着这样做:

elements[j] (reverse)?(<):(>) tempElement

但这是不正确的,不起作用。另外,三元运算符将if语句中的基本运算次数增加了一倍。我知道它只是一个插入排序,做Θ(n^2)次操作(不是对很多元素排序的最好方法),但我认为有更好的方法来写它。另外,你不能使用this:

(repeat)?(-1):(1) * (elements[j] - tempElement) > 0

因为类T只能有operator=和operator> (operator<)。你也不能在循环中调用函数,因为它将是Θ(n)或Θ(n^2)调用。下面是最后一个解决方案:

#ifndef INSERTIONSORT
#define INSERTIONSORT
template<class T> 
void insertionSort(T* elements, int size, int reverse = 0) {
    T tempElement;
    int j;
    if (reverse)
        for (int i = 0; i < size; ++i) {
            tempElement = elements[i];
            for (j = i - 1; j >= 0 && elements[j] < tempElement; j--)
                elements[j + 1] = elements[j];
            elements[j + 1] = tempElement;
        }
    else 
        for (int i = 0; i < size; ++i) {
            tempElement = elements[i];
            for (j = i - 1; j >= 0 && elements[j] > tempElement; j--)
                elements[j + 1] = elements[j];
            elements[j + 1] = tempElement;
        }
}
#endif

唯一的问题是重复代码。编程的主要原则是:"不要重复自己"。我真的不知道如何在这里正确地编写代码。

您可以添加比较器作为类型,如下面的示例所示:

template<template<class> class COMP = std::less, typename T> 
void insertionSort(T* elements, int size) {
    T tempElement;
    int j;
    COMP<T> pred;
    for (int i = 0; i < size; ++i) {
        tempElement = elements[i];
        for (j = i - 1; j >= 0 && pred(tempElement, elements[j]); --j)
            elements[j + 1] = elements[j];
        elements[j + 1] = tempElement;
    }
}

现场演示