演算法練習:產生指定範圍的隨機數
阿新 • • 發佈:2019-02-07
一、問題描述
給出一個整型陣列,以及一個區間範圍[min,max],寫一個函式產生一個在此區間範圍內的隨機數,並且該隨機數不在數組裡,假設總能找到該隨機數。
二、分析與解答
分成兩步,即可解答。第一步,生成一個隨機數x包含於[min,max];第二步,判斷此隨機數是否在陣列中,是的話重新生成一個隨機數再執行第二步,否則返回此隨機數。
在判斷隨機數是否在陣列中,如果採用順序查詢的方式,則查詢的時間複雜度為O(n)。在最壞的情況下,假設在產生的前n個隨機數都在陣列中,直到第n+1個才符合條件,那麼,整個演算法的時間複雜度為O(n^2)。
那麼,能否進一步提升效率呢,經分析,能提升的部分可以在判重的部分,先對陣列進行排序,然後利用二分查詢法,使查詢的時間複雜度從O(n)--->O(logn)
三、程式碼與實現
#include <iostream> #include <algorithm> #include <ctime> #include <cstdlib> using namespace std; int RandNumInRange( int nArray[], int nCount, int nMin, int nMax ) { if ( nMin > nMax ) { int temp = nMax; nMax = nMin; nMin = temp; } if ( nMin == nMax ) { return nMin; } int nRet = nMin + rand() % (nMax - nMin); if ( nArray == NULL || nCount <= 0 ) { return nRet; } //從小到大排序 sort( nArray, nArray+nCount ); while ( true ) { int low = 0; int high = nCount - 1; int mid = 0; bool bContinue = false; while( low <= high ) { mid = (low + high)/2; if ( nArray[mid] == nRet ) { bContinue = true; break; } else if ( nArray[mid] > nRet ) { high = high - 1; } else { low = low + 1; } } if ( !bContinue ) { break; } //再次生成一個隨機數 nRet = nMin + rand() % (nMax - nMin); } return nRet; } int main() { //隨機種子 srand( (unsigned)time( NULL ) ); int nArray[] = { 10, 12, 18, 14, 15, 13 }; for ( int i = 0; i < 20; ++i ) { cout << RandNumInRange( nArray, _countof(nArray), 5, 5 ) << endl; } return 0; }
系列文章說明:
1.本系列文章[演算法練習],僅僅是本人學習過程的一個記錄以及自我激勵,沒有什麼說教的意思。如果能給讀者帶來些許知識及感悟,那是我的榮幸。
2.本系列文章是本人學習陳東鋒老師《進軍矽谷,程式設計師面試揭祕》一書而寫的一些心得體會,文章大多數觀點均來自此書,特此說明!
3.文章之中,難免有諸多的錯誤與不足,歡迎讀者批評指正,謝謝.
作者:山丘兒
轉載請標明出處,謝謝。原文地址:http://blog.csdn.net/s634772208/article/details/46494611