不好意思,最近才发现这篇博文是错误的,在此指出,希望不会再误导他人,唉,学艺不精啊,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版的存在问题!!!
如有问题欢迎指正!!!