不好意思,最近才发现这篇博文是错误的,在此指出,希望不会再误导他人,唉,学艺不精啊,sorry,sorry!!!
先贴出G++的库函数的STL的代码:来源于ubuntu下文件/usr/include/c++/4.7/bits/stl_algo.h
/** * @brief Randomly shuffle the elements of a sequence. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @return Nothing. * * Reorder the elements in the range @p [__first,__last) using a random * distribution, so that every possible ordering of the sequence is * equally likely. */ template<typename _RandomAccessIterator> inline void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); if (__first != __last) for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1))); }
核心的代码在最后两行,其它的可以不关注。算法的核心就是:依次遍历迭代器,随机产生一个小于i的下标j,让当前下标为i的元素与下标为j的元素交换。无疑这样的算法并不能很好的将元素随机化,因为下标为i的元素更倾向与位于0-i之间。
改进后的算法:
/** * @brief Randomly shuffle the elements of a sequence. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @return Nothing. * * Reorder the elements in the range @p [__first,__last) using a random * distribution, so that every possible ordering of the sequence is * equally likely. */ template<typename _RandomAccessIterator> inline void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); srand((unsigned)time(NULL));//增加了这一行 if (__first != __last) for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) std::iter_swap(__i, __first + (std::rand() % (__last - __first)));//修改了这一行而已 }
为什么改进后的算法更好呢?STL版随机化算法能生成n!排列(包括重复的),而改进后的算法能生成nn种排列(包括重复的),而n个数的全排列为n!,也就是说STL版随机化算法不可能生成n个数的全排列,因为有重复的。当然这并不能直接说明改进后的算法好,但是至少说明了STL版的存在问题!!!
如有问题欢迎指正!!!