我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
当前回答
很简单,只需让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);
}
}
其他回答
使用复数,您可以有效地将否定数字的任务分为两个步骤:
将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。
int j = 0;
void int f(int n)
{
j++;
if(j==2)
{
j = 0;
return -n;
}
return n;
}
:D
记住你的上一个状态不是一个足够好的答案吗?
int f (int n)
{
//if count
static int count = 0;
if (count == 0)
{
count = 1;
return n;
}
if (n == 0)
return 0;
else if (n > 0)
{
count = 0;
return abs(n)*(-1);
}
else
{
count = 0;
return abs(n);
}
}
int main()
{
int n = 42;
std::cout << f(f(n))
}
这个怎么样(C语言):
int f(int n)
{
static int t = 1;
return (t = t ? 0 : 1) ? -n : n;
}
刚刚试过,而且
f(f(1000))
回报-1000
f(f(-1000))
返回1000
这是正确的还是我没有抓住重点?
这将在非常广泛的数字范围内发挥作用:
static int f(int n)
{
int lastBit = int.MaxValue;
lastBit++;
int secondLastBit = lastBit >> 1;
int tuple = lastBit | secondLastBit;
if ((n & tuple) == tuple)
return n + lastBit;
if ((n & tuple) == 0)
return n + lastBit;
return -(n + lastBit);
}
我最初的方法是使用最后一位作为检查位,以了解我们在第一次或第二次调用中的位置。基本上,我会在第一次调用后将此位设置为1,以向第二次调用发出第一次调用已经通过的信号。但是,这种方法被负数所击败,负数的最后一位在第一次调用期间已经到达1。
同样的理论适用于大多数负数的倒数第二位。但是,通常发生的情况是,大多数情况下,最后一位和第二位是相同的。它们要么都是负数的1,要么都是正数的0。
所以我的最后一个方法是检查它们是否都是1或都是0,这意味着在大多数情况下这是第一次调用。如果最后一位与第二个最后一位不同,那么我假设我们在第二次调用,然后简单地重新反转最后一位。显然,对于使用最后两位的非常大的数字来说,这不起作用。但是,它再次适用于非常广泛的数字。