LeetCode 第 231 題:"Power of Two",相當單純的題目。
Given an integer, write a function to determine if it is a power of two.
在之前做過 LeetCode 326 的 Power of Three, 我使用對數來處理,該實現代碼可以直接套用在 Power of Two 的需求上,但本文打算用 bits 來驗證該整數是否為 2 的次方數。
Step 1: n 為 0 或 負數,應回傳 false
測試代碼:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void n_is_less_or_equal_0_should_return_false()
{
var n = 0;
Assert.IsFalse(new Solution().IsPowerOfTwo(n));
}
}
通過測試的生產代碼:
public class Solution
{
public bool IsPowerOfTwo(int n)
{
if (n <= 0) return false;
throw new NotImplementedException();
}
}
重構 assertion:
Step 2: n 為 1,應為 2 的次方
測試代碼:
生產代碼,hard-code 通過 n = 1 回傳 true。
重構 assertion 的部分:
Step 3: n 為 2, 應為 2 的次方
測試代碼:
[TestMethod]
public void n_is_2_should_return_true()
{
ShouldBeTrue(2);
}
生產代碼:先用 mod 2 於 0 通過此測試案例。(hard-code 通過 test case 的情況)
Step 4: n 為 6, 為 2 的倍數,但非 2 的次方數
測試代碼:
生產代碼:將 n 轉成 2 進位,當 1 的數量只有一個時,代表為 2 的次方數。
重構:移除 n == 1 的判斷,因為 n == 1 的商業邏輯被包含在剛剛實現的代碼中。
Step 5: 重構,rename assertion function
將原本不具語意的 ShouldBeTrue()
與 ShouldBeFalse()
rename 為 IsPowerOfTwo()
與 IsNotPowerOfTwo()
通過 LeetCode 所有測試案例
摘要整理
- integer 轉成 2 進位字串,可用
Convert.ToString(n, 2)
- 次方數代表只有存在單一個
"1"
- 不要因為是測試程式或只是練習,而忽略了語意。語意的層次在解釋說明意義,而非說明實現過程的細節。
ShouldBeTrue()
就是實現細節。IsPowerOfTwo()
才是解釋意圖。(同理,測試案例名稱也應該修改,不該用should_be_true
而改採用should_be_power_of_two
GitHub Commit History: LeetCode 231. Power of Two