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

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

有什么想法吗?


当前回答

上述问题不要求函数只能接受32位整数,只要求给定的n是32位整数。

红宝石:

def f( n )
  return 0 unless n != 0 
  ( n == n.to_i ) ? 1.0 / n : -(n**-1).to_i
end

其他回答

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

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

类似于python中的函数重载解决方案:

def f(number):
 if type(number) != type([]):
  return [].append(number)
 else:
  return -1*number[0]

备选方案:静态数据成员

很简单,只需让f返回看起来等于任何整数的值,并且可以从整数转换。

public class Agreeable
{
    public static bool operator==(Agreeable c, int n)
        { return true; }

    public static bool operator!=(Agreeable c, int n)
        { return false; }

    public static implicit operator Agreeable(int n)
        { return new Agreeable(); }
}

class Program
{
    public static Agreeable f(Agreeable c)
        { return c; }

    static void Main(string[] args)
    {
        Debug.Assert(f(f(0)) == 0);
        Debug.Assert(f(f(5)) == -5);
        Debug.Assert(f(f(-5)) == 5);
        Debug.Assert(f(f(int.MaxValue)) == -int.MaxValue);
    }
}
int f(int n)
{
  static long counter=0;
  counter++;
  if(counter%2==0)
    return -n;
  else
    return n;
}

SQL Server中的解决方案

create function dbo.fn_fo(@num int) -- OUTER FUNCTION
RETURNS int
AS
begin
RETURN @num * -1
end
GO

create function dbo.fn_fi(@num int) -- INNER FUNCTION
RETURNS int
AS
begin
RETURN @num * -1
end
GO

declare @num AS int = -42
SELECT dbo.fn_fo(dbo.fn_fi(@num)) -- Gives (-42)