要求:求二進制數中1的個數
解法1:除、余操作 最常見的方法:使用相除判斷余數的方式來進行分析,若求模2 為1,則證明是1,求模2 為0,證明該二進制位置上面的0;/** * 計算二進制中1的個數 O(log2V) * @param v 10進制的數字 * @return 二進制中1的個數 */ public static int Count(int v) { int num = 0; while(0 != v) { if( 1 == v % 2) { num++; } v= v / 2; } return num; }該算法的時間復雜度為 O(log2n)
解法二:使用位操作 >>:右移運算符,將數往右移動,即去掉地位的數,高位補零。 如:v = v>>1,為,v向右移動一位 為了代替上面的除操作,這里使用右移一位的方式代替,為了看最低位是否為1,使用“與”操作/** * 使用位操作計算二進制中1的個數 *@param v 10進制的數字 * @return 二進制中1的個數 */ public static int Count2(int v) { int num = 0; while(0 != v) { num += v & 0x01; v = v >> 1; //v右移一位 } return num; }雖然說,原理上,上面兩種方式是一樣的,但位操作比除、余操作的效率高了很多。但即使使用位操作,時間復雜度認為O(log2N)
解法3: 基本思想:每次消除一個為1的二進制位 通過每次讓v和(v-1)進行相與即可消除最低位的1/** * 與上面的類似,時間復雜度為O(M),M為v中1的個數 * @param v * @return */ public static int Count3(int v) { int num = 0; while(0 != v) { v &= v-1; num++; } return num; }復雜度降低到了O(M),M為1的個數。
解法四:窮舉法 1、使用switch 2、初始化數組,數組中的值是下標值的1的位數這種方式是典型的空間換時間的方法,但是這種空間換時間的算法是不合理,需列舉出所有的可能。測試代碼
public static void main(String[] args) { int num = CountOfOne.Count(11); System.out.結果:
二進制中1的個數為:3二進制中1的個數為:3二進制中1的個數為:3
新聞熱點
疑難解答