算法设计中的基础常用代码
引言
本篇博客旨在記錄一些基礎算法知識的常見組合用法,以及何時使用,需要注意的問題等,長期更新。
為什么要這樣總結呢?難道掌握了位運算、常用算法工具API的定義還不夠嗎?
這是因為某些知識比如 &、 |、 ~、 Math.random 等這些基礎知識如果只停留在知識記憶層面還是無法快速運用到算法的解題思路中去,還應該有一套常見組合用法或使用規律。
這些組合用法通常并不是算法題的核心考點,但卻起到連接算法思想、基礎知識和解題實現的樞紐作用,就好比學習英語時,我們的目的是連詞成句,但單詞并不是簡單的拼湊就可以連成句子,而是需要中間結構——短語、常見搭配、語法、使用場景等多方面的經驗知識:
如上圖所示,光有基礎知識層是不夠的,如果想獲得算法層的能力,必須要總結各種基礎知識的常見組合,一旦我們在遇到算法題時,能夠快速定位需要的算法組合搭配和小而美的算法思想,最終的算法實現一定能夠成功落實。
一、Math.random()的應用
random()方法可以返回 [0, 1)之間的隨機數。
圍繞這個核心方法,推廣到以下一些常用場景,注意,以下范圍都是左右閉區間,如果是右開區間,需要考慮清楚是否要 +1:
1、得到 [0, range] 范圍內的一個int數?
(int) (Math.random() * ( range + 1))
2、得到 [1, range] 范圍內的一個int數?
(int) (Math.random() * range) + 1
3、萬能公式:min和max都是正整數,返回 [min, max] 范圍內的一個 int數?
(int) (Math.random() * (max - min + 1)) + min
4、max 是一個正整數,返回[-max, max]范圍內的一個int數?
(int) (Math.random() * (max + 1)) - (int) (Math.random() * (max + 1))
二、位運算的應用
&1 和 &0
在位運算中,&1用來保留原數,&0用來清除原數。例如,5(二進制:101),如何將其二進制位放入int[] 數組?或依次取得每個bit位上的值?
對于一個int型整數來說,其二進制長度是32bit,因此可以初始化一個空的int[32]數組,然后循環數組下標 i,然后逐位&1:
public static int[] getBits(int num) {int[] bits = new int[32];for (int i = 0; i < bits.length; i++) {bits[i] = (num >> i) & 1;}return bits;}這樣,移位后再&1就可以得到 i 位置上的二進制數。
有時候需要將多個數按位累加,bits[i] += (num >> i) & 1。這通常在詞頻統計的時候非常有用。
又比如,如何取某整數二進制位最右1?例如,12,二進制1100,取最右1,即100。方法是 num & ((~num) + 1),另外 (~num) + 1 也等于 -num。
public static int getMostRightOne(int num) {return num & ((~num) + 1);}|1?
在位運算中,|1通常用來設值,|0通常用來保留原數。
比如,按位設值,假如我們知道了某個數二進制位有值條件,那么就可以使用 |1的方法,將1逐位放入:
int num = 0; for(int i = 0; i < 32; i++) {if (該位有值的case) {num |= (1 << i);} } return num;^ 異或運算
異或運算可以很好的規避某些額外空間消耗的問題,例如兩數調換(注意,對于數組兩數調換,切記不可將相同位置調換,a[i]、a[j] 調換的話,一定不能讓 i 和 j 相等!),詞頻統計等,具體查看《異或運算的應用》,牢記以下幾點異或的特性:
特性1:0 ^ N = N
特性2:N ^ N = 0
特性3(交換律):a ^ b = b ^ a
特性4(結合律):(a ^ b) ^ c = a ^ (b ^ c)
特性3 和 4總結起來,就是同一批數,不論使用怎樣的順序,怎樣的結合方式進行異或,其結果始終一樣。
三、Arrays.copyOf(org, len)
拷貝一個原始數組 org,從0開始,長度是 len。該方法通常用作測試程序,生成一個對照數組。
?
總結
以上是生活随笔為你收集整理的算法设计中的基础常用代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 神经网络原理_神经网络理论
- 下一篇: spring读取properties配置