我上次面试时收到的一个问题:
设计一个函数
f
,使得:f(f(n)) == -n
当
n
是一个32位的有符号整数时,你不能使用复数运算。如果你不能为所有数字范围设计这样的函数,那就尽可能地为最大范围设计。
有什么想法吗?
#define STYPE int
STYPE sign_bit = (unsigned STYPE) 1 << ( sizeof ( STYPE ) * 8 - 1 );
STYPE f ( STYPE f )
{
unsigned STYPE smf = f > 0 ? f : -f | sign_bit;
smf += sign_bit >> 1;
return smf & sign_bit ? -( smf & ~sign_bit ) : smf;
}
function f(x) {
var neg = x < 0;
x = Math.abs(x) ^ 1;
if (x & 1) {
neg = !neg;
}
return neg ? -x : x;
}
function f(n)
if type(n) == "number" then
return (-number) .. ""
else
return number + 0
end
end
sealed trait IntWrapper {
val n: Int
}
case class First(n: Int) extends IntWrapper
case class Second(n: Int) extends IntWrapper
case class Last(n: Int) extends IntWrapper
implicit def int2wrapper(n: Int) = First(n)
implicit def wrapper2int(w: IntWrapper) = w.n
def f(n: IntWrapper) = n match {
case First(x) => Second(x)
case Second(x) => Last(-x)
}
我认为这不是完全正确的想法。
Last(-8)
隐式转换为 -8
,因此解决方案有效。 - Daniel Spiewakf(n) { return -1 * abs(n) }
Clojure解决方案:
(defmacro f [n] (如果 (list? n) `(- ~n) n))
适用于任何大小的正负整数、双精度浮点数和比例!
使用Coffeescript编写高尔夫球游戏:
f = (n)-> -n[0] or [n]
function f(n) { return -n[0] || [n] }
的函数。 - Ricardo Tomasidef f(n):
m = -n if n % 2 == 0 else n
return m + sign(n)
普遍情况
对上述方法稍作修改即可处理我们需要进行k
次自调用以否定输入的情况 - 例如,如果k = 3
,则意味着g(g(g(n))) = -n
:
def g(n):
if n % k: return n + sign(n)
return -n + (k - 1) * sign(n)
N * k + 1, N * k + 2, ... , N * k + (k - 1), - N * k - 1, ... , - N * k - (k - 1)
或者为了更容易理解,这里是以k = 3
为例的循环:
1, 2, 3, -1, -2, -3
4, 5, 6, -4, -5, -6
这组循环可以使得任何以零为中心的机器类型(如signed int32或signed int64类型)最大化输入范围。
兼容范围的分析
事实上,映射 x -> f(x)
必须形成长度为 2 * k
的循环,其中 x = 0
是一个特殊的 1 长度循环,因为 -0 = 0。因此对于一般的 k
,问题只有当输入范围-1(为了补偿0)是2 * k的倍数,并且正负范围相反时才可解决。
对于有符号整数表示,我们总是有一个最小的负数,其范围内没有正对应,因此问题在完整范围内变得无法解决。例如,signed char
的范围为[-128,127],因此在给定的范围内不可能使得 f(f(-128)) = 128
。
有些相似,但我想写下我的第一个想法(用C++)
#include <vector>
vector<int>* f(int n)
{
returnVector = new vector<int>();
returnVector->push_back(n);
return returnVector;
}
int f(vector<int>* n) { return -(n->at(0)); }
只需使用重载即可使 f(f(n)) 实际调用两个不同的函数
Scala:
def f(x: Any): Any = x match {
case i: Int => new { override def hashCode = -i }
case i @ _ => i.hashCode
}
Java 中的相同事物:
public static Object f(final Object x) {
if(x instanceof Integer) {
return new Object() {
@Override
public int hashCode() {
return -(Integer)x;
}
};
}
return x.hashCode();
}