我在上次面试中遇到的一个问题是:

设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。

有什么想法吗?


当前回答

它通过保存状态来作弊,但它有效,将操作分成两部分:-n=(~n+1)对于整数

int f(int n) {
    static int a = 1;
    a = !a;
    if (a) {
        return (~n);
    } else {
        return (n+1);
    }
}

其他回答

使用复数,您可以有效地将否定数字的任务分为两个步骤:

将n乘以i,得到n*i,n逆时针旋转90°再乘以i,得到-n

最棒的是,您不需要任何特殊的处理代码。只要乘以i就可以了。

但不允许使用复数。因此,您必须使用部分数据范围创建自己的虚拟轴。由于需要的虚(中间)值与初始值一样多,因此只剩下一半的数据范围。

我试图在下图中显示这一点,假设有符号的8位数据。您必须将其缩放为32位整数。初始n的允许范围为-64到+63。下面是函数对正n的作用:

如果n在0..63(初始范围)内,函数调用将添加64,将n映射到范围64..127(中间范围)如果n在64..127(中间范围)内,则函数从64中减去n,将n映射到范围0..-63

对于负n,函数使用中间范围-65..-128。

这个Perl解决方案适用于整数、浮点数和字符串。

sub f {
    my $n = shift;
    return ref($n) ? -$$n : \$n;
}

尝试一些测试数据。

print $_, ' ', f(f($_)), "\n" for -2, 0, 1, 1.1, -3.3, 'foo' '-bar';

输出:

-2 2
0 0
1 -1
1.1 -1.1
-3.3 3.3
foo -foo
-bar +bar

嗯,我既不是数学,也不是编程高手,但这不是很容易吗?

int f(int i) {
    static bool b;
    if (b) {
        b = !b;
        return i;
    } else {
        b = !b;
        return -i;
    }
}

用大小正值和负值INT_MIN、INT_MAX进行测试,似乎可以。。。如果这是一个问题,可以使线程安全,但这不是任务的一部分。

或者我错过了什么?

int f(int n)
{
  static long counter=0;
  counter++;
  if(counter%2==0)
    return -n;
  else
    return n;
}

这个想法已经在其他答案中使用过,但我把它融入了Python的一行:

def f(n):
    return str(n) if type(n) == int else -int(n)