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

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

有什么想法吗?


当前回答

另一个作弊解决方案。我们使用允许运算符重载的语言。然后我们让f(x)返回重载==的值,以始终返回true。这似乎与问题描述相符,但显然违背了谜题的精神。

Ruby示例:

class Cheat
  def ==(n)
     true
  end
end

def f(n)
  Cheat.new
end

这给了我们:

>> f(f(1)) == -1
=> true

而且(不太令人惊讶)

>> f(f(1)) == "hello world"
=> true

其他回答

目标-C

这适用于除“-1”以外的所有数字。

如果要从使用int转换为使用NSInt,那么可以将-1值设置为NULL,然后第二次将它们转换为+1,但我觉得NSInt欺骗了询问者的意图。


f(n):

-(int)f:(int)n {
    if (abs(n)==1) {
        n = -1;
    } else {
        if (abs(n)%2) {//o
            if (n>0) {//+
                n--;
                n*=+1;
            } else if (n<0) {//-
                n++;
                n*=+1;
            }
        } else {//e
            if (n>0) {//+
                n++;
                n*=-1;
            } else if (n<0) {//-
                n--;
                n*=-1;
            }
        }
    }
    return n;
}

当然,这一切都可以缩短为一行,但其他人可能无法阅读。。。

无论如何,我将BOOLEAN逻辑存储为奇数或偶数的状态。

void f(int x)
{
     Console.WriteLine(string.Format("f(f({0})) == -{0}",x));
}

抱歉,伙计们。。。这太诱人了;)

这个是Python中的。适用于n的所有负值:

f = abs

一个C++版本,可能会稍微改变规则,但适用于所有数值类型(浮点、整型、双精度),甚至是重载一元负号的类类型:

template <class T>
struct f_result
{
  T value;
};

template <class T>
f_result <T> f (T n)
{
  f_result <T> result = {n};
  return result;
}

template <class T>
T f (f_result <T> n)
{
  return -n.value;
}

void main (void)
{
  int n = 45;
  cout << "f(f(" << n << ")) = " << f(f(n)) << endl;
  float p = 3.14f;
  cout << "f(f(" << p << ")) = " << f(f(p)) << endl;
}

MIN_INT不会失败:

int f(n) { return n < 0 ? -abs(n + 1) : -(abs(n) + 1); }