1、比較簡單和容易理解的方法就是逐位比較法:
#include using這種方法的缺點是比較費時,時間長度取決於n的位數,時間複雜度o(n)。假如上千上萬位的話,每一位都要執行一遍,所用時間就很長了。namespace std;
int findone(unsigned int n)
int main()
2、最直接的優化方法,其實就是空間換時間的思想:可以預建立乙個表,存放了從0~2^32每個數中1的個數,用時去查一下表就知道了。但這樣顯然要耗費很多的空間(至少2^32/(256/32)=512mb,哈哈,正是一般記憶體大小)。於是需要再優化:存放0-255每個數中1的個數,然後分段查詢。如下面把32位數分為4段,每段乙個位元組,所以有乙個256大小供查詢的表:
char tone[256]="3、上次在阿里雲筆試,碰到一題也是求乙個整數中1的個數。\0\1\1\2\1\2……
"; //
後面省略
int findone(unsigned int n)
int
func(unsigned
int
n)
return
count;
}
比如n=10,二進位制為1010,count=2。
4、下面這種方法據說更快,但是我覺得不容易想出來。發現很多題目都可以用位運算來快速解決,可惜本人十分討厭使用它,總覺得在繞來繞去的,偉大的位運算...
int count_ones(unsigned a)該**的思路是這樣的:2位2位為一組,相加,看看有幾個1。再4位4位為一組,相加,看看有幾個1......
為了簡單說明,先看看8位的情形。相應地,函式裡面的語句變成。
x = (x & 0x55) + ((x >> 1) & 0x55); (1)
x = (x & 0x33) + ((x >> 2) & 0x33); (2)
x = (x & 0x0f) + ((x >> 4) & 0x0f); (3)
return x;
假設x=abcdefgh. 0x55=01010101
x & 0x55 = 0b0d0f0h. (x>>1) & 0x55 = 0a0c0e0g。相加。就可以知道2位2位一組1的個數。
比如x=11111111
x= (x & 0x55) + ((x >> 1) & 0x55); 之後x=10101010。你2位2位地看,10=2, 就是2 2 2 2, 就是說各組都是2個1。
比如x=00101001
x= (x & 0x55) + ((x >> 1) & 0x55); 之後x=00010101。你2位2位地看,就是0 1 1 1, 前1組只有0個1,後面的組都是1個1。
好啦。再來看。0x33=00110011。
x=abcdefgh.
x=(x & 0x33)+((x >> 2)&0x33); 相當於, 00ab00ef + 00cd00gh。
因為語句(1)之後。ab指示了頭兩位有多少個1,cd指示了下兩位有多少個1。相加00ab+00cd就指示前4位有多少個1。這樣就是4位4位為一組。注意這樣的分組,組與組之間永遠都不會產生進製的。正因為不會產生進製,才可以分開來看。
下面的過程都是一樣的,不再多說。8位,16位,32位都一樣。
判斷32位整數二進位制中1的個數
收藏此頁 列印 it168知識庫 判斷32位整數二進位制中1的個數 iostream using namespace std intfindone unsigned intn intmain 2 優化 這樣的時間複雜度是t m m,取決於二進位制數的位數m。如果要求在更短時間內求出,應該如何做呢?如...
判斷二進位製半整數(二進位制)
10年後,tokitsukaze大佬已經變成了年收入超百萬的的精英程式設計師,家裡沒錢也沒礦的teitoku,找tokitsukaze大佬借1000塊錢,然後tokitsukaze大佬說,借你1024吧,湊個整數。沒錯在2進製下1024是 二進位制整數 乙個正整數滿足其值為2的k次方 k為正整數 我...
判斷二進位製半整數
判斷二進位製半整數 時間限制 c c 1秒,其他語言2秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 10年後,tokitsukaze大佬已經變成了年收入超百萬的的精英程式設計師,家裡沒錢也沒礦的teitoku,找tokitsukaze大佬借10...