我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
当前回答
我想我会先不看别人的答案就试试这个:
#include <stdio.h> #include <limits.h> #include <stdlib.h> int f(int n) { if(n > 0) { if(n % 2) return -(++n); else { return (--n); } } else { if(n % 2) return -(--n); else { return (++n); } } } int main(int argc, char* argv[]) { int n; for(n = INT_MIN; n < INT_MAX; n++) { int N = f(f(n)); if(N != -n) { fprintf(stderr, "FAIL! %i != %i\n", N, -n); } } n = INT_MAX; int N = f(f(n)); if(N != -n) { fprintf(stderr, "FAIL! n = %i\n", n); } return 0; }
输出:[无]
其他回答
这很简单!
每个数字以4为周期映射到另一个数字,其中所需条件成立。
例子:
规则如下:
0→ 0±2³¹ → ±2³¹古怪的→ 甚至,甚至→ -奇数:对于所有k,0<k<2³⁰: (2k-1)→ (2k)→ (-2k+1)→ (-2k)→ (2k-1)
唯一不匹配的值是±(2³¹-1),因为只有两个。必须有两个不能匹配,因为在二进制补码系统中只有四个数字的倍数,其中0和±2³¹已被保留。
在一的补码系统中,存在+0和-0。我们开始了:
对于所有k,0<k<2³⁰: (+2k)→ (+2k+1)→ (-2k)→ (-2k-1)→ (+2k)
void f(int x)
{
Console.WriteLine(string.Format("f(f({0})) == -{0}",x));
}
抱歉,伙计们。。。这太诱人了;)
C#表示2^32-1个数字的范围,所有整数32(int32.MinValue除外)
Func<int, int> f = n =>
n < 0
? (n & (1 << 30)) == (1 << 30) ? (n ^ (1 << 30)) : - (n | (1 << 30))
: (n & (1 << 30)) == (1 << 30) ? -(n ^ (1 << 30)) : (n | (1 << 30));
Console.WriteLine(f(f(Int32.MinValue + 1))); // -2147483648 + 1
for (int i = -3; i <= 3 ; i++)
Console.WriteLine(f(f(i)));
Console.WriteLine(f(f(Int32.MaxValue))); // 2147483647
打印:
2147483647
3
2
1
0
-1
-2
-3
-2147483647
容易的:
function f($n) {
if ($n%2 == 0) return ($n+1)*-1;
else return ($n-1);
}
这个怎么样(C语言):
int f(int n)
{
static int t = 1;
return (t = t ? 0 : 1) ? -n : n;
}
刚刚试过,而且
f(f(1000))
回报-1000
f(f(-1000))
返回1000
这是正确的还是我没有抓住重点?