自定义is_sorted功能模板

时间:2013-05-14 03:45:42

标签: c++ templates

我想编写自己的is_sorted函数模板实现,而不是使用std :: is_sorted。你能告诉我怎么做的吗? 我想只将它用于数组。所以我想做这样的声明:

template <typename T, size_t N>
bool is_sorted (const T (&array)[N]); and 

bool operator>(const A &, const A &); is declared.

2 个答案:

答案 0 :(得分:4)

显而易见的方法是将每个项目与之后的项目进行比较,看看是否&lt; =到那个项目。

你可能不想直接这样做。首先,对于排序,客户通常只需要确保定义a < b,因此您希望使用<而不是<=。其次,您希望允许(但不要求)用户传递自己的比较器,以防<未直接为某种类型定义,或者所需的排序使用的标准与<不同定义

因此,您可能希望定义两个版本的is_sorted,一个直接使用<,另一个使用用户传递的比较器。

#include <iterator>
#include <functional>

template <class InIt>
bool is_sorted(InIt b, InIt e) {
    if (b == e)           // No items -- sorted by definition
        return true;

    typename std::iterator_traits<InIt>::value_type first = *b;
    ++b;
    while (b != e) {    // skip if e-b == 1 (single item is sorted)
        if (*b < first)
            return false;
        first = *b;
        ++b;
    }
    return true;
}

template <class InIt, class Cmp>
bool is_sorted(InIt b, InIt e, Cmp cmp) { 
    if (b == e)
        return true;

    typename std::iterator_traits<InIt>::value_type first = *b;
    ++b;
    while (b != e) {    // skip if e-b == 1 (single item is sorte)
        if (cmp(*b, first))
            return false;
        first = *b;
        ++b;
    }
    return true;
}

使用std::vectorstd::dequestd::array和内置数组,使用排序,未排序,相同和反转的元素保持诚实,一些测试代码:

#ifdef TEST
#include <array>
#include <vector>
#include <iostream>
#include <deque>

int main() { 
    std::vector<int> sorted{1, 2, 3, 4, 6, 100};
    std::deque<int> unsorted{1, 5, 2, 7, 4};
    std::array<int, 7> ident = {1, 1, 1, 1, 1, 3, 3};
    int rev[] = {5, 4, 3, 2, 1};

    if (!is_sorted(std::begin(sorted), std::end(sorted)))
        std::cout << "Sorted array detected as un-sorted\n";
    if (is_sorted(std::begin(unsorted), std::end(unsorted)))
        std::cout << "Un-sorted array detected as sorted\n";
    if (!is_sorted(std::begin(ident), std::end(ident)))
        std::cout << "sorted array with duplicated detected as un-sorted\n";
    if (!is_sorted(std::begin(rev), std::end(rev), std::greater<int>()))
        std::cout << "Reverse sorted array detected as un-sorted\n";
    return 0;
}
#endif

对于gcc 4.7.2,这对我来说很好。 is_sorted代码似乎也适用于VC ++ 2012(尽管测试代码需要一些小的修改,例如,为了消除统一初始化的使用,它还不支持)。

编辑:如果你不介意对迭代器(转发迭代器而不是输入迭代器)的要求稍微严格一些,你就可以使代码更简单,而且效率更高。例如,代码可以缩减为:

template <class FwdIt>
bool is_sorted(FwdIt b, FwdIt e) {
    if (b == e)           // No items -- sorted by definition
        return true;

    for (FwdIt first = b; ++b != e; first = b) 
        if (*b < *first)
            return false;    
    return true;
}

答案 1 :(得分:2)

确保容器中的每个元素都是<=下一个元素。

如果您只有一个<比较器(与大多数STL算法一样),请确保容器中没有元素,其中给定元素是<前一个元素。