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

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

有什么想法吗?


当前回答

我还没有看其他答案,我假设已经彻底讨论了按位技术。

我想我会在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(); }

其他回答

const unsigned long Magic = 0x8000000;

unsigned long f(unsigned long n)
{    
    if(n > Magic )
    {
        return Magic - n;
    }

    return n + Magic;
} 

0~2^31

在Python中

f=lambda n:n[0]if type(n)is list else[-n]

另一种方法是将状态保持在一位,并在负数的情况下翻转它,注意二进制表示。。。限制为2^29

整数ffn(整数n){

    n = n ^ (1 << 30); //flip the bit
    if (n>0)// if negative then there's a two's complement
    {
        if (n & (1<<30))
        {
            return n;
        }
        else
        {
            return -n;
        }
    }
    else
    {
        if (n & (1<<30))
        {
            return -n;
        }
        else
        {
            return n;
        }
    }


}

用咖啡脚本打高尔夫:

f = (n)-> -n[0] or [n]

我希望你改变2个最高有效位。

00.... => 01.... => 10.....

01.... => 10.... => 11.....

10.... => 11.... => 00.....

11.... => 00.... => 01.....

正如你所看到的,这只是一个补充,省去了进位。

我是怎么得到答案的?我的第一个想法就是需要对称。4转回到我开始的地方。起初我想,这是20比特的格雷码。然后我觉得标准二进制就足够了。