《編程珠璣》習題1.4:如果認真考慮了習題3,你將會面對生成小于n且沒有重復的k個整數的問題。最簡單的方法就是使用前k個正整數。這個極端的數據集合將不會明顯的改變位圖方法的運行時間,但是可能會歪曲系統排序的運行時間。如何生成位于0至n - 1之間的k個不同的隨機順序的隨機整數?盡量使你的程序簡短高效。
如下的程序產生1-n的不重復的隨機數:
~~~
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
void produce (int a[], int n) {
int i;
//對數組a依次賦一個不同的值
for (i = 0; i < n + 1; i++) {
a[i] = i + 1;
}
srand((int)time(0));
//下面的語句用于產生n個不同的隨機數,存于數組的0到n-1位中
// i + rand() % (n - i)產生一個范圍i到n的隨機數
//那么將這個下標的數組數據和以i為下標的數組數據swap肯定不重復
for (i = 0; i < n; i++) {
swap(&a[i], &a[i + rand() % (n - i)]);
}
}
~~~
上面的算法復雜度為O(n);
在文章[Libnids的哈希函數](http://blog.csdn.net/u013074465/article/details/45061605)中,libnids的void?init_hash?()?函數也提供了一種產生0到11之間不重復隨機數的方法,其復雜度為O(n ^ 2).
參考:
[http://blog.chinaunix.net/uid-21228455-id-2406483.html](http://blog.chinaunix.net/uid-21228455-id-2406483.html)
[http://blog.csdn.net/wdzxl198/article/details/12000091](http://blog.csdn.net/wdzxl198/article/details/12000091)
- 前言
- Josephus約瑟夫問題及其變種
- 鏈表的常見實現
- 二叉樹遍歷、插入、刪除等常見操作
- 二叉堆的插入刪除等操作C++實現
- 插入排序和希爾排序
- 堆排序
- 歸并排序及其空間復雜度的思考
- 快速排序的幾種常見實現及其性能對比
- 紅黑樹操作及實現
- 整數的二進制表示中1的個數
- 位操作實現加減乘除四則運算
- 冒泡排序的改進
- 直接選擇排序
- 不借助變量交換兩個數
- 基礎排序算法總結
- AVL樹(Adelson-Velskii-Landis tree)
- avl樹的C++實現
- 動態規劃之鋼條分割
- hash函數的基本知識
- 動態規劃:求最長公共子串/最長公共子序列
- 最長遞增子序列
- 稱砝碼問題
- 汽水瓶
- 字符串合并處理(二進制位的倒序)
- 動態規劃:計算字符串相似度
- m個蘋果放入n個盤子
- 生成k個小于n的互不相同的隨機數
- 棧和隊列的相互模擬
- 字符串的排列/組合
- KMP(Knuth-Morris-Pratt)算法
- n個骰子的點數
- 位運算的常見操作和題目