我正在尝试检查一个数字(输入为String
)是否为2的幂。问题是该数字可能大于2^64
(长期限制长度)。如果我将它存储在double
中,那么我就不能对它进行二进制操作(因此技巧v & (v - 1) == 0
不起作用)。这是我偶然发现的解决方案:
public class Solution {
public int power(String A) {
String dividend = A;
StringBuilder str;
if (A == null || A.length() == 0)
return 0;
if (A.length() == 1 && A.charAt(0) == '0')
return 0;
while (dividend.length() > 0 && !dividend.equalsIgnoreCase("2")) {
str = new StringBuilder();
int carry = 0;
int n = dividend.length();
if (n > 0) {
int num = dividend.charAt(n - 1) - '0';
if (num % 2 == 1)
return 0;
}
for (int i = 0; i < n; i++) {
char c = (char) (dividend.charAt(i) - '0');
int res = c + 10 * carry;
c = (char) (res / 2 + '0');
carry = res % 2;
str.append(c);
}
if (str.charAt(0) == '0')
str.deleteCharAt(0);
dividend = str.toString();
}
return 1;
}
}
我在理解解决方案时遇到了问题。如果数字是奇数,则完成第一次检查。我在理解在这个问题中完成的手动除法的实现方面遇到了问题(尤其是涉及char和int的算术运算)。我得到'0' == 48
并从字符中减去'0'
将其转换为整数值。任何人都可以向我解释这个分区操作是如何实现的吗?谢谢!
答案 0 :(得分:0)
理解此实现的最简单方法是进行纸笔测试。我将跳过你理解的部分,只关注最后一个for
循环。
让我们以"50"
作为示例输入。从左侧开始,循环以字符顺序逐步执行String
。因此,处理的第一个字符是'5'
。如您所知,5
很奇怪。这意味着我们必须&#34;携带&#34;进入下一个部门的东西。 5 / 2
的结果是2
。此2
将是该部门结果的第一位数字。请注意,如果我们撤消我们的步骤,我们会得到2 * 2
,即4
。这就是我们必须携带一些东西的原因(1
缺失,因为5 - 4
是1
)。您可能会注意到,如果除以2,则可以携带0
(无)或1
(当且仅当被除数为奇数时)。
现在转到下一个数字,即0
。我们必须将最后一个部门的1
带到此步骤。由于我们向左移动了一位数字,因此在此步骤中,previos步骤中的1
变为10
。我们将#34;向下移动了一个数量级,因此我们必须将进位部分乘以10
。这意味着我们计算(0 + (1 * 10)) / 2
,即10 / 2
= 5
。此5
是结果的第二个数字。由于股息是均匀的,我们不需要继续分红。
因此,最终输出为"25"
,正如预期的那样。
答案 1 :(得分:0)
str = new StringBuilder();
int carry = 0;
int n = dividend.length();
if (n > 0) {
int num = dividend.charAt(n - 1) - '0';
分开输入。它取字符串末尾的字符,并从该值取值&#39; 0&#39; http://www.asciitable.com/ - 对于&#39; 0&#39;它是48.所以它给出了那个小数的值,没有任何解析。
if (num % 2 == 1)
return 0;
}
接下来for循环将divided
除以2。这是通过辅助每个数字来完成的。从第一个到最后一个。下一次迭代从prev获得值。
for (int i = 0; i < n; i++) {
char c = (char) (dividend.charAt(i) - '0');
如前所述 - 它&#39; c&#39;是带十进制值的字节。
int res = c + 10 * carry;
&#39; RES&#39;也随身携带。
c = (char) (res / 2 + '0');
特殊条目的划分在这里完成。添加&#39; 0&#39;是简单的转换为字符/字符串,
carry = res % 2;
请注意,我们将从头开始,而不是从头开始。所以随身携带 到下一次迭代是模数。
str.append(c);
}
if (str.charAt(0) == '0')
str.deleteCharAt(0);
只需删除前导零
即可 dividend = str.toString();
转换回字符串,再次调用除法。
答案 2 :(得分:0)
//试试这个!
double n = scanner.nextInt();
while (n > 1) {
n = n / 2;
}
System.out.println(n);
if (n == 1)
System.out.println("true");
else
System.out.println("false");