前言
最近在學習算法題,周末無事閑逛圖書館,偶然在一本算法書中看到枚舉算法,其中的一個案例感覺很有趣就特此做個記錄。
問題
輸入一個正整數num,判斷num是否能被3,5,7整除,并輸出以下信息:
(1)能同時被3,5,7整除。
(2)能同時被其中兩個數(要指出哪兩個數)整除。
(3)能被其中一個數整除。
(4)不能被任何一個整除。
解題
最直接、暴力的方式就是簡約的if、else判斷,比如:
if(num%3==0 && num%5==0 && num%7==0)
...
雖然結果沒問題、代碼也簡單,但會有多層判斷,if嵌套也是越來越深,所以使用枚舉算法可以讓書面代碼看起來更加的干凈。
-
先來張圖做解釋
拆解圖
將目標數對3、5、7分別取余,能整除記作1,不能整除記作0。然后將對3整除的標記向左移動2位,將對5整除的標記向左移動1位,再把3個標記位相加即可變成上圖的二進制標記位,最后將二進制對應成十進制就是我們要找的case。
比如num=21,21%3=0記作1,21%5=1記作0,21%7=0記作1,那么進行左移和相加計算后,得到二進制數101,對應十進制數5,那么即可走入相應的case。 接下來上代碼
// Swift版
func test(_ num: Int) {
let c1: Int = num%3==0 ? 1 : 0
let c2: Int = num%5==0 ? 1 : 0
let c3: Int = num%7==0 ? 1 : 0
switch (c1<<2) + (c2<<1) + c3 {
case 0:
print("均不可被3、5、7整除")
break
case 1:
print("可被7整除")
break
case 2:
print("可被5整除")
break
case 3:
print("可被5、7整除")
break
case 4:
print("可被3整除")
break
case 5:
print("可被3、7整除")
break
case 6:
print("可被3、5整除")
break
case 7:
print("可被3、5、7整除")
break
default:
break
}
}
另外,不必糾結為啥第一位是對3整除,第二位是對5整除,第三位是對7整除,他們只是標記而已。比如將對3整除和對7整除互換位置也是可以的。當然,底下的case也要將3、7值互換。
多謝支持!