我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
当前回答
这里有一个解决方案,其灵感来自于不能使用复数来解决这个问题的要求或声明。
乘以-1的平方根是一个想法,但似乎失败了,因为-1没有整数的平方根。但是,使用mathematica这样的程序可以得出如下公式
(18494364652+1)模(232-3)=0。
这几乎和平方根为-1一样好。函数的结果必须是有符号整数。因此,我将使用一个修改的模运算mods(x,n),它返回与x模n最接近0的整数y。只有极少数编程语言能够成功地进行模运算,但它很容易被定义。例如,在python中,它是:
def mods(x, n):
y = x % n
if y > n/2: y-= n
return y
使用上面的公式,问题现在可以解决为
def f(x):
return mods(x*1849436465, 2**32-3)
对于[-231-2231-2]范围内的所有整数,这满足f(f(x))=-x。f(x)的结果也在这个范围内,但当然计算需要64位整数。
其他回答
Tcl:
proc f {input} {
if { [string is integer $input] } {
return [list expr [list 0 - $input]]
} else {
return [eval $input]
}
}
% f [f 1]
-1
按照其他一些答案的思路。。。如果它是一个整数,则返回一个返回该数字负数的命令。如果不是数字,请对其求值并返回结果。
对于javascript(或其他动态类型语言),可以让函数接受int或对象,并返回另一个。即
function f(n) {
if (n.passed) {
return -n.val;
} else {
return {val:n, passed:1};
}
}
给
js> f(f(10))
-10
js> f(f(-10))
10
或者,您可以在强类型语言中使用重载,尽管这可能会破坏规则
int f(long n) {
return n;
}
long f(int n) {
return -n;
}
Lua:
function f(n)
if type(n) == "number" then
return (-number) .. ""
else
return number + 0
end
end
C函数:
int f(int n) /* Treats numbers in the range 0XC0000000 to 0X3FFFFFFF as valid to
generate f(f(x)) equal to -x. If n is within this range, it will
project n outside the range. If n is outside the range, it will
return the opposite of the number whose image is n. */
{
return n ? n > 0 ? n <= 0X3FFFFFFF ? 0X3FFFFFFF + n : 0X3FFFFFFF - n :\
n >= 0XC0000000 ? 0XC0000000 + n : 0XC0000000 - n : 0;
}
Ideone测试和下载链接
我还没有看其他答案,我假设已经彻底讨论了按位技术。
我想我会在C++中想出一些邪恶的东西,希望不会上当受骗:
struct ImplicitlyConvertibleToInt
{
operator int () const { return 0; }
};
int f(const ImplicitlyConvertibleToInt &) { return 0; }
ImplicitlyConvertibleToInt f(int & n)
{
n = 0; // The problem specification didn't say n was const
return ImplicitlyConvertibleToInt();
}
整个ImplicitlyConvertableToInt类型和重载是必需的,因为临时变量不能绑定到非常量引用。
当然,现在来看它,f(n)是否在-n之前执行是不确定的。
对于这种程度的邪恶,也许一个更好的解决方案是:
struct ComparesTrueToInt
{
ComparesTrueToInt(int) { } // implicit construction from int
};
bool operator == (ComparesTrueToInt, int) const { return true; }
ComparesTrueToInt f(ComparesTrueToInt ct) { return ComparesTrueToInt(); }