LeetCode 231. Power of Two

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 所有測試案例

摘要整理

  1. integer 轉成 2 進位字串,可用 Convert.ToString(n, 2)
  2. 次方數代表只有存在單一個 "1"
  3. 不要因為是測試程式或只是練習,而忽略了語意。語意的層次在解釋說明意義,而非說明實現過程的細節。ShouldBeTrue() 就是實現細節。IsPowerOfTwo() 才是解釋意圖。
GitHub Commit History: LeetCode 231. Power of Two 

blog 與課程更新內容,請前往新站位置:http://tdd.best/