1. 程式人生 > >演算法練習:產生指定範圍的隨機數

演算法練習:產生指定範圍的隨機數

一、問題描述

給出一個整型陣列,以及一個區間範圍[minmax],寫一個函式產生一個在此區間範圍內的隨機數,並且該隨機數不在數組裡,假設總能找到該隨機數。

二、分析與解答

分成兩步,即可解答。第一步,生成一個隨機數x包含於[minmax];第二步,判斷此隨機數是否在陣列中,是的話重新生成一個隨機數再執行第二步,否則返回此隨機數。

在判斷隨機數是否在陣列中,如果採用順序查詢的方式,則查詢的時間複雜度為O(n)。在最壞的情況下,假設在產生的前n個隨機數都在陣列中,直到第n+1個才符合條件,那麼,整個演算法的時間複雜度為O(n^2)

那麼,能否進一步提升效率呢,經分析,能提升的部分可以在判重的部分,先對陣列進行排序,然後利用二分查詢法,使查詢的時間複雜度從O(n)--->O(logn)

。所以整個演算法的時間複雜度為O(nlogn)

三、程式碼與實現

#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