真是很極端的做法啊
宋寶華 [email protected] 軟體報
問題:對於乙個位元組(8bit)的資料,求其中「1」的個數,要求演算法的執行效率盡可能地高。
分析:作為一道著名外企的面試題,看似簡單,實則可以看出乙個程式設計師的基本功底的紮實程度。你或許已經
想到很多方法,譬如除、餘操作,位操作等,但都不是最快的。本文一步步分析,直到最後給出乙個最快的方
法,相信你看到本文最後的那個最快的方法時會有驚詫的感覺。
解答:首先,很自然的,你想到除法和求餘運算,並給出了如下的答案:
方法1:使用除、餘操作
#include
#define byte unsigned char
int main(int argc, char *argv)
a = a / 2;
}printf("/nthe num of 1 in the byte is %d", num);
return 0;
}很遺憾,眾所周知,除法操作的運算速率實在是很低的,這個答案只能意味著面試者被淘汰!
好,精明的面試者想到了以位操作代替除法和求餘操作,並給出如下答案:
方法2:使用位操作
#include
#define byte unsigned char
int main(int argc, char *argv)
/*或者這樣計算1 的個數:*/
/* for(i=0;i<8;i++)
*/printf("/nthe num of 1 in the byte is %d", num);
return 0;
}方法二中num += (a >> i) &0x01;操作的執行效率明顯高於方法一中的
if (a % 2 == 1)
a = a / 2;
到這個時候,面試者有被錄用的可能性了,但是,難道最快的就是這個方法了嗎?沒有更快的了嗎?方法二真
的高山仰止了嗎?
能不能不用做除法、位操作就直接得出答案的呢?於是你想到把0~255 的情況都羅列出來,並使用分支操作,
給出如下答案:
方法3:使用分支操作
#include
#define byte unsigned char
int main(int argc, char *argv)
printf("/nthe num of 1 in the byte is %d", num);
return 0;
}方法三看似很直接,實際執行效率可能還會小於方法二,因為分支語句的執**況要看具體位元組的值,如果a=0,
那自然在第1 個case 就得出了答案,但是如果a=255,則要在最後乙個case 才得出答案,即在進行了255
次比較操作之後!
看來方法三不可取!但是方法三提供了乙個思路,就是羅列並直接給出值,離最後的方法四只有一步之遙。眼
看著就要被這家著名外企錄用,此時此刻,絕不對放棄尋找更快的方法。
終於,靈感一現,得到方法四,乙個令你心潮澎湃的答案,快地令人咋舌,演算法中不需要進行任何的運算。你
有足夠的信心了,把下面的答案遞給面試官:
方法4:直接得到結果
#include
#define byte unsigned char
/* 定義查詢表 */
byte numtable[256] =
;int main(int argc, char *argv)
這是個典型的空間換時間演算法,把0~255 中1 的個數直接儲存在陣列中,位元組a 作為陣列的下標,checknum[a]
直接就是a 中「1」的個數!演算法的複雜度如下:
時間複雜度:o(1)
空間複雜度:o(2n)
恭喜你,你已經被這家著名的外企錄用!老總向你伸出手,說:「welcome to our company」
不知道嵌入式那點記憶體是否允許鼓勵這樣做。
經典 反轉乙個位元組
這道題很古老了,可別將它和大端轉小端混淆了,所謂大端和小端指的是位元組序,而這裡反轉乙個位元組說的是位序,演算法更是不勝列舉,說實話都能達到目的,剩餘的就是看看誰的效率更高了,基本上這是乙個最難的問題,高手不是能寫出最美麗的程式而是能寫出既美麗同時效率又是最高的程式,如果乙個人寫的程式很美麗,很直觀...
乙個字等於多少位元組?
在這個特定計算機中,字是其用來一次性處理事務的乙個固定長度的位 bit 組。現代計算機的字長通常為16 32 64位。結合以上兩句,我覺得乙個字佔多少位元組並不是那麼絕對的,要看你是哪個處理器 處理器的位數決定了能夠處理一條指令的長度 以前我看書上也是說乙個字就是兩個位元組,這是因為我們之前接觸的8...
筆試題 反轉乙個位元組
這道題很古老了,可別將它和大端轉小端混淆了,所謂大端和小端指的是位元組序,而這裡反轉乙個位元組說的是位序,演算法更是不勝列舉,說實話都能達到目的,剩餘的就是看看誰的效率更高了,基本上這是乙個最難的問題,高手不是能寫出最美麗的程式而是能寫出既美麗同時效率又是最高的程式,如果乙個人寫的程式很美麗,很直觀...