我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
我在上次面试中遇到的一个问题是:
设计函数f,使得:f(f(n))==-n其中n是32位有符号整数;你不能用复数算术。如果你不能为整个数字范围设计这样的函数,那么就尽可能为最大范围设计它。
有什么想法吗?
当前回答
int f( int n ){
return n==0?0:(n&1?n:-n)+(n<0?-1:1);
}
其他回答
根据微软/谷歌的面试官通常在面试中提出的问题,我认为提问者指的是一种创新、轻量级、简单的解决方案,它将使用按位操作,而不是那些复杂的高级答案。
灵感来自@eipipuz的回答,我编写了这个C++函数(但没有运行它):
int32_t f(int32_t n){
int32_t temp = n & 00111111111111111111111111111111;
x = n >> 30;
x++;
x = x << 30;
return x | temp;
}
它将n的最左边的两位存储在x中,将x加1,然后再次将其替换为n的最左侧的两位。
如果我们继续以另一个f(n)作为参数n运行f(n,则最左边的两个位将如下旋转:
00 --> 01 --> 10 --> 11 --> 00 ...
请注意,最右边的30位不变。8位整数示例:
示例1:
>f(00001111)=01001111>f(01001111)=10001111[这是原始值的负值,00001111]
示例2:
>f(11101010)=00101010>f(00101010)=01101010[这是原始值11101010的负值]
没有人说它必须是无国籍的。
int32 f(int32 x) {
static bool idempotent = false;
if (!idempotent) {
idempotent = true;
return -x;
} else {
return x;
}
}
作弊,但不如很多例子。更糟糕的是,查看堆栈以查看调用者的地址是否为-f,但这将更具可移植性(虽然不是线程安全的……线程安全版本将使用TLS)。更邪恶的是:
int32 f (int32 x) {
static int32 answer = -x;
return answer;
}
当然,对于MIN_INT32的情况,这两种方法都不太有效,但除非允许返回更宽的类型,否则对此您几乎无能为力。
很简单,只需让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);
}
}
void f(int x)
{
Console.WriteLine(string.Format("f(f({0})) == -{0}",x));
}
抱歉,伙计们。。。这太诱人了;)
怎么样:
f(n) = sign(n) - (-1)ⁿ * n
在Python中:
def f(n):
if n == 0: return 0
if n >= 0:
if n % 2 == 1:
return n + 1
else:
return -1 * (n - 1)
else:
if n % 2 == 1:
return n - 1
else:
return -1 * (n + 1)
Python自动将整数提升为任意长度的longs。在其他语言中,最大的正整数将溢出,因此它将适用于除该整数之外的所有整数。
为了使其适用于实数,您需要替换(-1)中的nⁿ 如果n>0,则为{上限(n);如果n<0},则为下限(n)。
在C#中(适用于任何双精度,溢出情况除外):
static double F(double n)
{
if (n == 0) return 0;
if (n < 0)
return ((long)Math.Ceiling(n) % 2 == 0) ? (n + 1) : (-1 * (n - 1));
else
return ((long)Math.Floor(n) % 2 == 0) ? (n - 1) : (-1 * (n + 1));
}