Algorithms_入门基础_如何使用最高效的方式来判断一个数是否是2的N次方
文章目錄
- Question
- Answer 1.0
- Answer 2.0 按位與運(yùn)算 &
- 須知
- 十進(jìn)制轉(zhuǎn)二進(jìn)制
- 八位二進(jìn)制
- 按位與運(yùn)算 &
Question
引入… 先看個(gè)阿里巴巴的面試題吧
如何使用最高效的方式來(lái)判斷一個(gè)數(shù)是否是2的N次方? 先思考下哈
…
…
…
…
…
…
…
…
…
…
…
…
…
…
Answer 1.0
分析下:
2的N次方嘛 ,舉個(gè)例子 2 4 8 16是 2的N次方, 6 , 10 不是2的N次方。
2的N次方 ====> 就可以看成 這個(gè)數(shù)是不是可以拆成 N個(gè)2相乘嘛
那根據(jù)這個(gè)思路的話 ,寫(xiě)個(gè)偽代碼
while(n>1){n % 2 == 0 ---> 如果除以2不為0 ,肯定不是2的N次方 n = n / 2 ; ---> 繼續(xù)除以2 (即我們上面說(shuō)的拆成N個(gè)2),循環(huán)判斷 }分析好了,我們來(lái)用Java語(yǔ)言實(shí)現(xiàn)下
/*** @author 小工匠* @version v1.0* @create 2019-11-19 21:22* @motto show me the code ,change the word* @blog https://artisan.blog.csdn.net/* @description**/public class Test {/*** 思路:* 如果某個(gè)數(shù)除以2 不等于0 ,最起碼已經(jīng)不是2的倍數(shù)了,更不要是2的N次方了 ,* 比如 3 ,5 ,7這種數(shù)字* 利用該特性循環(huán)判斷** @param args*/public static void main(String[] args) {int n = 6;// 原始數(shù)值int temp = n; // 臨時(shí)變量while (temp > 1) {// while循環(huán)if (temp % 2 == 0) { // 判斷是否是2的倍數(shù)temp = temp / 2; // 除以2 繼續(xù)下一次的循環(huán)判斷System.out.println(temp == 1 ? ("原始數(shù)值【" + n + "】是2的N次方") : ("分析中...." + temp));} else {// 不是2的倍數(shù),肯定不是2的N次方了,直接break跳出循環(huán)System.out.println(n + "不是2的N次方");break;// 終止循環(huán)}}} }好了,算是實(shí)現(xiàn)了, 其實(shí)看看這個(gè)代碼是比較挫的,有沒(méi)有更好的思路呢 ?
提示一下: 按位與運(yùn)算
Answer 2.0 按位與運(yùn)算 &
為啥能想到這種思路,其實(shí)也是要靠積累的,對(duì)數(shù)字要有足夠的敏感,看到某個(gè)十進(jìn)制的數(shù),可以馬上想到對(duì)應(yīng)的二進(jìn)制數(shù)。
八位二進(jìn)制嘛 ,為啥是8位,請(qǐng)移步下方的須知
我們來(lái)看下幾個(gè)數(shù)字
2 ,4 ,8 ,16
我們來(lái)看下 2 ,4 ,8 ,16 這幾個(gè)十進(jìn)制的是 對(duì)應(yīng)的 二進(jìn)制 ,咋算的 請(qǐng)移步下方的須知
2 = 10 ---->補(bǔ)位湊成8位 -----> 00000010 4 = 100 ---->補(bǔ)位湊成8位 -----> 00000100 8= 1000 ---->補(bǔ)位湊成8位 -----> 00001000 16=10000 ---->補(bǔ)位湊成8位 -----> 00010000接下來(lái)我們看下 比2 4 8 16 小1的十進(jìn)制整數(shù),對(duì)應(yīng)的二進(jìn)制
2 = 10 ---->補(bǔ)位湊成8位 -----> 00000010 1 = 01 ---->補(bǔ)位湊成8位 -----> 000000014 = 100 ---->補(bǔ)位湊成8位 -----> 00000100 3 = 011 ---->補(bǔ)位湊成8位 -----> 000000118 = 1000 ---->補(bǔ)位湊成8位 -----> 00001000 7 = 0111 ---->補(bǔ)位湊成8位 -----> 00000111 16 = 10000 ---->補(bǔ)位湊成8位 -----> 00010000 15 = 01111 ---->補(bǔ)位湊成8位 -----> 00001111按二進(jìn)制位進(jìn)行“與”運(yùn)算 ,只有兩個(gè)數(shù)的二進(jìn)制同時(shí)為1,結(jié)果才為1,否則為0。
我們看下上面的規(guī)律哈 n 和 n-1 這兩個(gè)十進(jìn)制的整數(shù) ,按照二進(jìn)制進(jìn)行 按位與運(yùn)算后,為0,那么這個(gè)n就是2的N次方。
偽代碼如下
if((n & (n-1)) == 0)) -----> n 就是 2的次方接下來(lái)我們用java實(shí)現(xiàn)以下
/*** @author 小工匠* @version v1.0* @create 2019-11-19 21:27* @motto show me the code ,change the word* @blog https://artisan.blog.csdn.net/* @description**/ public class TestA {/*** 思路:* 按位與運(yùn)算 & , 兩個(gè)數(shù)字按照二進(jìn)制的形式進(jìn)行"與"運(yùn)算 ,如果結(jié)果為0 ,則是2的N次方* @param args*/public static void main(String[] args) {int n = 128 ;System.out.println((n&(n-1)) == 0 ? n + "是2的N次方" : n + "不是2的N次方");} }須知
十進(jìn)制轉(zhuǎn)二進(jìn)制
十進(jìn)制整數(shù)轉(zhuǎn)換為二進(jìn)制整數(shù)采用"除2取余,逆序排列"法。
具體做法:
用2整除十進(jìn)制整數(shù),可以得到一個(gè)商和余數(shù);
再用2去除商,又會(huì)得到一個(gè)商和余數(shù),如此進(jìn)行,直到商為小于1時(shí)為止,
然后把先得到的余數(shù)作為二進(jìn)制數(shù)的低位有效位,后得到的余數(shù)作為二進(jìn)制數(shù)的高位有效位,依次排列起來(lái)。
一圖勝千言 ,來(lái)吧
八位二進(jìn)制
我們常說(shuō) “八位二進(jìn)制” ,到底是啥意思嘞 ?
說(shuō)起二進(jìn)制 ,其實(shí)就要從計(jì)算機(jī)的的組成-電子元件說(shuō)起, 這些元件一般都是只有兩種穩(wěn)定的工作狀態(tài),用高、低兩個(gè)電位表示“0”和“1”在物理上是最容易實(shí)現(xiàn)的。
那八位二進(jìn)制又是什么妖魔鬼怪呢? 我們知道 電腦的最小存儲(chǔ)單位是字節(jié)Byte ,即我們常說(shuō)的大B, 一個(gè)字節(jié), 是由八位二進(jìn)制位組成的,就是這八位數(shù)字只是由“0”和“1”兩個(gè)數(shù)字組成 ,比如 11111000,00000001,00000101等等。
八位二進(jìn)制 就是一個(gè)字節(jié)(Byte)的大小。
1個(gè)英文字母、英文標(biāo)點(diǎn)、半角數(shù)字 在計(jì)算機(jī)是以八位二進(jìn)制數(shù)保存 就是一個(gè)字節(jié)大小,
1個(gè)漢字(包括中文標(biāo)點(diǎn) 全角數(shù)字)就是2個(gè)字節(jié) (十六位二進(jìn)制)
1位二進(jìn)制大小就是1bit ,就是我們說(shuō)的 小b。
在計(jì)算機(jī)科學(xué)中,bit通常用于表示信息的最小單位,也可以被稱作是二進(jìn)制位。在計(jì)算機(jī)學(xué)科中,bit一般用0和1表示。Byte也就是人們常說(shuō)的字節(jié),通常由8個(gè)位(8bit)組成一個(gè)字節(jié)(1Byte)
比如我們常見(jiàn)的基本類型的取值范圍
bit與Byte之間可以進(jìn)行換算,具體的換算關(guān)系為:1Byte=8bit
在計(jì)算機(jī)網(wǎng)絡(luò)或者是網(wǎng)絡(luò)運(yùn)營(yíng)商中,一般而言,寬帶速率的單位用bps(或b/s)表示;bps表示比特每秒即表示每秒鐘傳輸多少位信息,是bit per second的縮寫(xiě) 小b 。 在實(shí)際所說(shuō)的1M帶寬的意思是1Mbps(是兆比特每秒Mbps不是兆字節(jié)每秒MBps)。
1B=8b 1B/s=8b/s(或1Bps=8bps)1KB=1024B 1KB/s=1024B/s1MB=1024KB 1MB/s=1024KB/s規(guī)范提示:實(shí)際書(shū)寫(xiě)規(guī)范中B應(yīng)表示Byte(字節(jié)),b應(yīng)表示bit(比特),但在平時(shí)的實(shí)際書(shū)寫(xiě)中有的把bit和Byte都混寫(xiě)為b ,如把Mb/s和MB/s都混寫(xiě)為Mb/s,導(dǎo)致人們?cè)趯?shí)際計(jì)算中因單位的混淆而出錯(cuò)。切記注意!!!
按位與運(yùn)算 &
定義: 參加運(yùn)算的兩個(gè)數(shù),按二進(jìn)制位進(jìn)行“與”運(yùn)算
運(yùn)算規(guī)則:只有兩個(gè)數(shù)的二進(jìn)制同時(shí)為1,結(jié)果才為1,否則為0。
比如 0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1。
舉個(gè)例子 :
3 &5 即 00000011 & 00000101 = 00000001 ,所以 3 & 5的值為1。
總結(jié)
以上是生活随笔為你收集整理的Algorithms_入门基础_如何使用最高效的方式来判断一个数是否是2的N次方的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Apache Kafka-初体验Kafk
- 下一篇: Algorithms_入门基础_时间复杂