前言
最近在学习算法题,周末无事闲逛图书馆,偶然在一本算法书中看到枚举算法,其中的一个案例感觉很有趣就特此做个记录。
问题
输入一个正整数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值互换。
多谢支持!
网友评论