前两天看见一个人这样说,面试的时候考试一道题,深入的问,很多人败下阵来。
但是要看是什么题目了。
编写函数,判断一个传入参数是不是奇数。
这之前什么无脑科技和短路电子提供的答案比如print 不返回true false的咱们略过不表。
我们先来看一个非常直观的答案:
def isOdd(number): return ( (number % 2) == 1)
这样,比如传入一个number=21,则输出True。挺简单的不是吗。相信有些人会想这家公司疯了吧,拿一道都没超过程序设计课程第二章的题目来做面试题,有什么目的?
确实有点问题在里面。
你算了个被2求余数不假,但是………………谁告诉你负数就没有奇数啊?那么,一个数%2,负数的结果是什么呢?python程序员就比较幸运了……呼呼,version 3.7运行结果是1,这个没问题。怎么样,是不是很想打开IDE或者启动一个notebook看一下?建议还是看看另一算式:number % -2 在您的惯用语言是什么结果,省的面试官问了现场想哦。
如果fu—cking缺德的语言底层,给你处理成一个………………number mod 2 = -1,不就麻烦了?为了可移植性,来吧,做一个-1版本-version for -1:
def isOdd(number): return ( abs(number % 2) == 1)
哇哈哈,abs函数真好用。但是文章作者显然没想过放开可怜的面试者,这样的运算时间是多少?还有更快的答案吗?拐来拐去,最后落到了位运算。最后是这么一个不直观的答案:
1. def isOdd(number): 2. return ((1 & number) == 1)
其实上面的答案因为运算符优先级(看看,优先级没背熟吃亏了吧我天)的关系,可以不要括号,1 & number ==1 是一样的,加上括号可以防止读起来有歧义啊。
因为number不管是奇数偶数,表示成二进制就是1和0组合,奇数的末尾一位是1。和1按位与,前面若干个位都成0,符号位也是0,最后一位是1。这样,奇数按位与就是1,偶数就是0。
然后发现还少点啥?异常?传入参数校验?对啊,你怎么知道传入参数不是字符串不是float。还得写校验啊:
def isOdd(number): if type(number) != int: raise TypeError("parameter is NOT an Integer.") return ((1 & number) == 1)
然后验算一下:
>>> isOdd(22) False >>> isOdd(23) True >>> isOdd(23.5) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in isOdd TypeError: parameter is NOT a Integer. >>> isOdd("hello") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in isOdd TypeError: parameter is NOT a Integer.