Algorithm 使用1位变量确定数字是否为数字回文

Algorithm 使用1位变量确定数字是否为数字回文,algorithm,bit-manipulation,Algorithm,Bit Manipulation,我在一个显示谷歌面试问题的网站上看到过这个问题 我不知道如何解决这个问题 如果允许我们保留一些其他变量,那么我建议保留两个索引,一个指向开始,另一个指向结束。然后使用bit变量比较其中两个变量(通过位操作) 但是如果不允许我们使用更多的变量,我不知道如何解决它。对于2n位的数字是回文,位置I的每一位都必须等于索引(2n-I)的位。 使用异或(XOR)很容易比较单个位: 当且仅当位a和b不相等时,XOR b==1。 因此,当我们以这种方式比较每一对对应的位(见上文)并通过对所有单位比较结果进行OR

我在一个显示谷歌面试问题的网站上看到过这个问题

我不知道如何解决这个问题

如果允许我们保留一些其他变量,那么我建议保留两个索引,一个指向开始,另一个指向结束。然后使用bit变量比较其中两个变量(通过位操作)


但是如果不允许我们使用更多的变量,我不知道如何解决它。

对于2n位的数字是回文,位置I的每一位都必须等于索引(2n-I)的位。 使用异或(XOR)很容易比较单个位: 当且仅当位a和b不相等时,XOR b==1。
因此,当我们以这种方式比较每一对对应的位(见上文)并通过对所有单位比较结果进行ORing来构建结果时,回文数为0,其他任何数字为1。

我假设我们讨论的是位回文(即3=11是,但2=10不是)

我认为有两种可能性:

(我为每一个都编写了一些Java代码。一些括号仅用于可读性)

  • 索引不算作变量。

    我要说的第一件事可能是“但指数是变量……”

    我们可以在数字上循环,一旦出现不匹配,就返回

    下面的数字是一个变量,但只是为了可读性,它可以被替换到if语句中

    数字的公式
    是经过一番周折后产生的(可能有一种更简单的方法)

    boolean isPalidrome(整数)
    {
    整数位数=(int)Math.ceil(Math.ceil(Math.log10(1+number)/Math.log10(2))-1;
    对于(int i=0;number/2>>i!=0;i++)
    {
    如果((数字>>i)&1)!=((数字>>位数-i)&1)))
    返回false;
    }
    返回true;
    }
    
  • 指数作为变量计算。

    假设给定了一个固定大小的数字(例如,
    int
    ,它是32位),这可以通过展开上面的循环来实现

    我将类型改为
    byte
    ,因为我真的看不到从本质上复制那么多行的意义<代码>字节只有8位,所以我们只需要4次检查,带中断条件

    同样地,
    数字
    是一个变量,但不需要是

    boolean isPalidrome(字节数)
    {
    整数位数=(int)Math.ceil(Math.ceil(Math.log10(1+number)/Math.log10(2))-1;
    如果((数字和1)!=((数字>>数字和1)))
    返回false;
    如果((数字/2>>1)==0)
    返回true;
    如果((数字>>1)&1)!=((数字>>(数字-1))&1)))
    返回false;
    如果((数字/2>>2)==0)
    返回true;
    如果((数字>>2)和1)!=((数字>>(数字-2))和1)))
    返回false;
    如果((数字/2>>3)==0)
    返回true;
    如果((数字>>3)和1)!=((数字>>(数字-3))和1)))
    返回false;
    返回true;
    }
    
    如果需要,也可以将上述内容固定在一条语句中

    如果允许我们修改实际的数字,也可以检查第一位和最后一位,如上所述,但随后修改数字以去除第一位和最后一位,因此我们可以再次检查第一位和最后一位,直到数字为零


请注意,上面的任何一个都没有使用位变量。可能位变量只是用来跟踪数字是否为回文的标志。

如果没有某种使用索引变量的for循环,您将如何进行所有的单位比较?我假设n是已知的且恒定的。但是,我们甚至不需要1位变量。另一方面,我们可以重复使用输入所存储的变量,并且在没有实际计数器的情况下继续工作?好吧,很公平。如果您有一些重用输入的具体算法,请随意发布。但一定要先测试它-有一些隐藏的复杂性,比如尝试
10011
。我不认为
n
是“已知且恒定的”,但假设它有一个上限可能就足够了(你可以)。搜索“比特旋转黑客”以查找可用于构建此回文检测器的常见比特黑客。关于提出的修改原始数字的最终选项(“如果允许我们修改实际数字…”),如果我们无法维护索引,这将不起作用。考虑二进制字符串10101。如果你去掉第一个和最后一个1,那么剩下的是(0)10。除非我们保存了索引,否则我们会认为我们的“最后一位”是1而不是0,并且无法正确进行比较。@ChaimKut您可以始终将最重要的
1
保留在那里,检查并剥离第二个MSB和LSB—可能不是那么容易,但可能是这样。