我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
当前回答
f#中的简单解决方案(不使用“技巧”)
let rec f n =
if n = 0 then 0
elif n > 0 then
if (f (n - 1) <> n) then n + 1
else -(n - 1)
else
if (f (-(n - 1)) = n) then n - 1
else -(n + 1)
其他回答
int f( int n ){
return n==0?0:(n&1?n:-n)+(n<0?-1:1);
}
记住你的上一个状态不是一个足够好的答案吗?
int f (int n)
{
//if count
static int count = 0;
if (count == 0)
{
count = 1;
return n;
}
if (n == 0)
return 0;
else if (n > 0)
{
count = 0;
return abs(n)*(-1);
}
else
{
count = 0;
return abs(n);
}
}
int main()
{
int n = 42;
std::cout << f(f(n))
}
该问题表示“32位有符号整数”,但没有指定它们是2个补码还是1个补码。
如果使用1补码,则所有2^32值都出现在长度为4的循环中-不需要零的特殊情况,也不需要条件。
在C中:
int32_t f(int32_t x)
{
return (((x & 0xFFFFU) << 16) | ((x & 0xFFFF0000U) >> 16)) ^ 0xFFFFU;
}
这项工作由
交换高位和低位16位块反转其中一个块
两次传递后,我们得到原始值的位逆。在一中补语表示等同于否定。
示例:
Pass | x
-----+-------------------
0 | 00000001 (+1)
1 | 0001FFFF (+131071)
2 | FFFFFFFE (-1)
3 | FFFE0000 (-131071)
4 | 00000001 (+1)
Pass | x
-----+-------------------
0 | 00000000 (+0)
1 | 0000FFFF (+65535)
2 | FFFFFFFF (-0)
3 | FFFF0000 (-65535)
4 | 00000000 (+0)
我不知道这是否完全正确,但一个简单的标志不起作用吗?在C语言中,使用静态局部变量,我成功地做到了这一点:
int main()
{
int n = -256; // 32-bit signed integer
printf("%d", f(f(n)));
}
int f(int n){
static int x = 0; // not returning negative;
switch(x){
case 0:
x = 1;
return n;
break;
case 1:
x = 0;
return -n;
break;
default:
return -999;
break;
}
}
这也是一个解决方案(但我们稍微改变了一下规则):
def f(n):
if isinstance(n,int):
return str(n)
else:
return -int(n)