代码之家  ›  专栏  ›  技术社区  ›  Phil H

有没有更有效的方法来排序两个数字?

c++
  •  3
  • Phil H  · 技术社区  · 15 年前

    我想要 dLower dHigher 分别拥有两个双精度值的低值和高值,也就是说,如果它们是错误的,就对它们进行排序。最直接的答案是:

    void ascending(double& dFirst, double& dSecond)
    {
        if(dFirst > dSecond)
            swap(dFirst,dSecond);
    }
    
    ascending(dFoo, dBar);
    

    但这似乎是一件显而易见的事情,我想知道我是否只是没有使用正确的术语来找到一个标准的例行程序。

    另外,您如何使其成为通用的?

    5 回复  |  直到 15 年前
        1
  •  4
  •   Magnus Hoff    15 年前

    这是一个接近它的好方法。它和你将要得到的一样有效。 我怀疑这个特定的函数有一个公认的名称。 这显然被称为比较交换。

    在类型上归纳它就像:

    template <typename T>
    void ascending(T& dFirst, T& dSecond)
    {
        if (dFirst > dSecond)
            std::swap(dFirst, dSecond);
    }
    

    证实此功能:

    int main() {
        int a=10, b=5;
        ascending(a, b);
        std::cout << a << ", " << b << std::endl;
    
        double c=7.2, d=3.1;
        ascending(c, d);
        std::cout << c << ", " << d << std::endl;
    
        return 0;
    }
    

    印刷品:

    5, 10
    3.1, 7.2
    
        2
  •  3
  •   Steve Jessop    15 年前

    玩“非常普通”的游戏:

    template <typename T, typename StrictWeakOrdering>
    void comparison_swap(T &lhs, T &rhs, StrictWeakOrdering cmp) {
        using std::swap;
        if (cmp(rhs, lhs)) {
            swap(lhs, rhs);
        }
    }
    
    template <typename T>
    void comparison_swap(T &lhs, T &rhs) {
        comparison_swap(lhs, rhs, std::less<T>());
    }
    

    这将勾选以下框:

    • 使用一个小于比较器,因为它在标准算法中使用,所以更容易用于用户定义的类型。
    • 比较器是 任选地 可配置,并默认为一些合理的(您可以使用 std::greater<T> 作为默认设置(如果您愿意并进行相应修改)。它还保证对同一类型的任意指针有效,这是 operator< 不是。
    • 使用 std::swap ,或者 swap ADL找到的函数,以防T类型提供一个而不是另一个。

    不过,我可能忘记了一些盒子。

        3
  •  2
  •   bjskishore123    15 年前

    正如你所问的,

    有更有效的分类方法吗 两个数字?

    考虑到效率,您可能需要编写自己的交换函数,并根据std::swap测试其性能。

    这是微软的实现。

    template<class _Ty> inline
        void swap(_Ty& _Left, _Ty& _Right)
        {   // exchange values stored at _Left and _Right
        if (&_Left != &_Right)
            {   // different, worth swapping
            _Ty _Tmp = _Left;
    
            _Left = _Right;
            _Right = _Tmp;
            }
        }
    

    如果你感觉到这种情况 if (&_Left != &_Right) 不需要检查,可以通过命令来提高代码的性能。您可以编写自己的交换,如下所示。

    template <class T>
    inline void swap(T &left, T& right)
    {
        T temp = left;
        left = right;
        right = temp;
    }
    

    对我来说,10千万次通话的性能似乎略有提高。 无论如何,您需要正确地度量与性能相关的更改。不要以为。

    某些库函数在编写时可能不会运行得太快,因为它们考虑到了一般用法、错误检查等。如果性能在应用程序中不是关键的,建议使用库函数,因为它们经过了良好的测试。

    如果性能像硬实时系统一样至关重要,那么编写和使用自己的系统没有任何错误。

        4
  •  2
  •   EboMike    15 年前

    让我在这里提出一个特殊的例子,它只适用于性能是一个绝对关键的问题,并且如果浮点精度足够:您可以考虑向量管道(如果您的目标CPU有一个)。

    有些CPU可以用一条指令来获取一个向量的每个组件的最小值和最大值,因此您可以一次处理4个值,而不需要任何分支。

    同样,这是一个非常特殊的案例,很可能与你正在做的事情无关,但我想提出这个问题,因为“更有效”是问题的一部分。

        5
  •  1
  •   Klaim    15 年前

    为什么不将std::sort()与lambda或函数一起使用?