演算法設計 如何求出乙個64位數中哪一位是 1

2021-06-22 09:37:30 字數 1149 閱讀 9452

今天在寫遊戲的時候,有這麼乙個需求:

我需要根據乙個標示符的值,標示符的值一般都是用這樣的數值來表示:

如用(1 << 2) 這個來標示乙個可以被渲染的物件, (1 << 3) 來標示乙個可以進行碰撞的物件,諸如此類的。

所以,我需要根據上面的標示符來獲取上面標示符中哪一位為1?

也就是說,對於(1 << 2) 這個值, 它的第2位為1(從下標為0開始計算)。

對於這樣的乙個演算法問題,很容易想到,對每乙個位使用邏輯運算來判斷下,這樣就能夠簡單的獲取到哪一位為1了。

對,採用這樣的方法,在演算法設計上,稱為蠻力法。蠻力法是乙個問題的最直接,最容易想到,也是最標準的做法了。但是,由於遊戲的效率問題,我這個函式要頻繁的呼叫,所以我想將它稍微的提高一下效率。

最近瀏覽了下《演算法設計與分析基礎》,大體的內容沒有仔細的看,只是簡單的瀏覽了下,設計演算法時的幾種有效工具,以及他們的思想。

所以,我一下就想到,使用分治法來設計這個演算法。

下面演算法的概要描述:

我們假設,這個標示符,使用64位無符號整形來表示,那麼,我們每一次將這個值折半,也就是說,將64位分為兩個部分,分別是高位部分,和低位部分,他們都是有32位組成的。然後在對這32位的值,不停的進行折半,知道最後折半成為1位的數,然後我們在來對這個1位的數判斷,是否為1,這樣我們就能夠計算出哪乙個值為1了。

(感覺上,好像和蠻力法的效果一樣啊???由於對於演算法複雜度分析還不是很了解,所以就暫時不管是否真的比蠻力法高效了^_^)

最後給出程式的**,很顯然,使用分治法,需要用到遞迴,所以,我使用遞迴來設計這個函式,而且,讀者請注意,這個演算法只是針對整形資料中,只有一位為1的情況,如果有多個位為1,這種行為,程式未對其進行考慮。以下是最終的**:

unsigned int getbitone64(unsigned _int64 value, unsigned int number, int index)

else

}// end for getbitone64

很簡短的一段**。

上面的**有幾個地方需要注意,這些地方都是我寫**的時候犯錯的地方。

好了,上面兩點就是在設計過程中遇到的主要問題,明白了這些細節,也就不是很麻煩了。

上面的演算法,很容易移植到32位,16位中去,感興趣的讀者,可以自行進行移植。

演算法設計 如何求陣列中第2大的數

一種思路是利用兩次冒泡法,因為第一次冒泡,最大的在a n 1 第二次冒泡後,次最大值在a n 2 這樣直接返回即可。核心 如下 for int i 0 i 2 i for int j 0 ja j 1 swap a j a j 1 return a n 2 但是這樣做,顯然效率不夠高,幾乎要遍歷兩次...

6 4 兩個兩位數合併成乙個四位數(函式題)

編寫函式fun,該函式的功能是 將兩個兩位數的正整數a和b合併成乙個整數放在c中。合併的方式為 將a的十位數和個位數依次放在c的十位和千位上,b數的十位和個位數字依次存放在c數的百位和個位上。例如,若a 34,b 26,呼叫函式後,求得c 4236。void fun int a,int b,long...

判斷乙個五位數是不是回文數

方法一 只限於五位數,而且笨 判斷乙個五位數是否為回文數 萬位與各位相等,千位與十位相等 如 12321 public static void main string args else double型別轉換為int型別不需要強制轉換如 int a 12321 10000 a的值為1,不為1.232...