我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
当前回答
这个是Python中的。适用于n的所有负值:
f = abs
其他回答
这也是一个解决方案(但我们稍微改变了一下规则):
def f(n):
if isinstance(n,int):
return str(n)
else:
return -int(n)
Lua:
function f(n)
if type(n) == "number" then
return (-number) .. ""
else
return number + 0
end
end
这是一个C/C++解决方案,它不使用任何按位运算符,也不需要任何数学库,尽管这有点作弊。。。
double f(double n)
{
if (n == (double)(int)n)
return n + 0.5;
else
return -(n - 0.5);
}
这适用于所有32位整数,只有一个异常0x80000000(因为它的相反值不能存储在32位整数系统中)。f(f(n))==-n将始终为真,除非在这种情况下。
不过,我相信有一种更简单、更快的方法来实现它。这只是我第一个想到的。
根据微软/谷歌的面试官通常在面试中提出的问题,我认为提问者指的是一种创新、轻量级、简单的解决方案,它将使用按位操作,而不是那些复杂的高级答案。
灵感来自@eipipuz的回答,我编写了这个C++函数(但没有运行它):
int32_t f(int32_t n){
int32_t temp = n & 00111111111111111111111111111111;
x = n >> 30;
x++;
x = x << 30;
return x | temp;
}
它将n的最左边的两位存储在x中,将x加1,然后再次将其替换为n的最左侧的两位。
如果我们继续以另一个f(n)作为参数n运行f(n,则最左边的两个位将如下旋转:
00 --> 01 --> 10 --> 11 --> 00 ...
请注意,最右边的30位不变。8位整数示例:
示例1:
>f(00001111)=01001111>f(01001111)=10001111[这是原始值的负值,00001111]
示例2:
>f(11101010)=00101010>f(00101010)=01101010[这是原始值11101010的负值]
除int.MaxValue和int.MinValue以外的工作
public static int f(int x)
{
if (x == 0) return 0;
if ((x % 2) != 0)
return x * -1 + (-1 *x) / (Math.Abs(x));
else
return x - x / (Math.Abs(x));
}