计算二进制间隙时无限循环
Infinite while loop while counting binary gap
我目前正在解决二进制间隙问题(计算两个 1 之间的 0 的数量,并返回找到的 0 的最大间隙),我的解决方案首先从将整数 N 转换为字符串开始N 的二进制形式,工作正常。
从概念上讲,我正在做的(或者至少我认为我正在做的)是计算 0 直到我达到 1 字符,然后将其与变量 gap
下的当前 0 计数进行比较,然后我将我的零计数器清零 zero_count
,我还添加了一个 if 语句来检查它到达二进制字符串末尾的情况,如果没有则返回 0,如果找到则返回 1。
出于某种原因,我得到了一个无限循环,我想我已经将它缩小到索引值不递增,但我不确定为什么。如果有人能解释一下,我将不胜感激!
这是在 Java 中完成的。
import java.util.*;
class Solution {
public int solution(int N) {
// write your code in Java SE 8
String binary = "";
int power = 31;
//double expo = Math.pow(2,power);
while(power !=-1){
if(N - Math.pow(2,power) > -1){
binary += "1";
N -= Math.pow(2,power);
}
else{binary += "0";}
power--;
}
System.out.println(binary);
//above works
int gap = 0;
int zero_count = 0;
int index = 0;
for( int i = 0; i < binary.length(); i++){
if(binary.charAt(i) == '1'){
index= i+1;
while(binary.charAt(index) =='0'){
index++;
zero_count++;
if(index == binary.length()-1){
return 0;
}
}
}
if(zero_count > gap){
gap = zero_count;
zero_count = 0;
}
i = index;
}
return gap;
}
}
循环太多..
将 main 添加到 drive/run 代码;您可以删除方法上的静态。
import java.util.*;
class Solution {
public static void main(String[] args) {
System.out.println("the max gap is: "+ Solution.solution(103241));
}
public static int solution(int N) {
// write your code in Java SE 8
String binary = "";
int power = 31;
//double expo = Math.pow(2,power);
while(power !=-1){
if(N - Math.pow(2,power) > -1){
binary += "1";
N -= Math.pow(2,power);
}
else{binary += "0";}
power--;
}
System.out.println(binary);
//above works
int max_gap = 0;
int zero_count = 0;
int index = 0;
//boolean
for( int i = 0; i < binary.length(); i++){
if(binary.charAt(i) == '0') {
zero_count++;
}
else {
if (zero_count > max_gap){
max_gap = zero_count;
}
zero_count = 0;
}
}
return max_gap;
}
}
嵌套 while
循环中存在几个问题:
- 在比较
index
处的字符时应检查 binary
的长度以避免 StringOutOfBoundsException
- 到达字符串末尾时不应 return
0
- 结果可能不正确
index
应该在离开 while
循环时递减
- 前导
0
s 应该完全跳过以避免无限循环
此外,构建 binary
string: 也存在问题
- 它不能正确转换负数
也就是说,以下代码解决了上述问题:
public static int solution(int N) {
// write your code in Java SE 8
String binary = "";
if (N == 0) {
binary = "0"; // shortcut for 0
} else {
N &= Integer.MAX_VALUE; // remove sign bit for negative numbers
while(N != 0) {
binary = (N & 1) + binary; // get rid of leading zeros
N >>= 1;
}
}
//above works
int gap = 0;
int zero_count = 0;
for (int i = 0, len = binary.length(); i < len; i++) {
if (binary.charAt(i) == '1') {
i++;
while (i < len && binary.charAt(i) == '0') {
zero_count++;
if (i == len - 1) {
zero_count = 0;
}
i++;
}
i--;
}
if (zero_count > gap) {
gap = zero_count;
zero_count = 0;
}
}
return gap;
}
但是,可以使用 Java 8 中可用的以下工具来实施更简单的解决方案:
Integer::toBinaryString
获取不带前导零的二进制字符串
String::replaceAll
删除尾随零
Pattern::splitAsStream
将剩余的字符串除以 1
并得到 Stream<String>
- common Stream API
mapToInt
, max
获取仅由零组成的子串的最大长度:
static int maxZeroGap(int n) {
return Pattern.compile("1")
.splitAsStream(
Integer.toBinaryString(n).replaceAll("0+$", "")
)
.mapToInt(String::length)
.max()
.orElse(0);
}
测试:
int[] nums = {
0, 1, -1, -1023, Integer.MIN_VALUE, 0b10, 0b11, 0b101, 0b1001, 0b100101, 0b101000, 0b1000000100001
};
for (int i : nums) {
System.out.printf("%d -> %s%n", i, Integer.toBinaryString(i));
int z = maxZeroGap(i);
System.out.println("max zeros = " + z + "; solution=" + solution(i));
System.out.println("--------------------");
}
输出
0 -> 0
max zeros = 0; solution=0
--------------------
1 -> 1
max zeros = 0; solution=0
--------------------
-1 -> 11111111111111111111111111111111
max zeros = 0; solution=0
--------------------
-1023 -> 11111111111111111111110000000001
max zeros = 9; solution=9
--------------------
-2147483648 -> 10000000000000000000000000000000
max zeros = 0; solution=0
--------------------
2 -> 10
max zeros = 0; solution=0
--------------------
3 -> 11
max zeros = 0; solution=0
--------------------
5 -> 101
max zeros = 1; solution=1
--------------------
9 -> 1001
max zeros = 2; solution=2
--------------------
37 -> 100101
max zeros = 2; solution=2
--------------------
40 -> 101000
max zeros = 1; solution=1
--------------------
4129 -> 1000000100001
max zeros = 6; solution=6
--------------------
我目前正在解决二进制间隙问题(计算两个 1 之间的 0 的数量,并返回找到的 0 的最大间隙),我的解决方案首先从将整数 N 转换为字符串开始N 的二进制形式,工作正常。
从概念上讲,我正在做的(或者至少我认为我正在做的)是计算 0 直到我达到 1 字符,然后将其与变量 gap
下的当前 0 计数进行比较,然后我将我的零计数器清零 zero_count
,我还添加了一个 if 语句来检查它到达二进制字符串末尾的情况,如果没有则返回 0,如果找到则返回 1。
出于某种原因,我得到了一个无限循环,我想我已经将它缩小到索引值不递增,但我不确定为什么。如果有人能解释一下,我将不胜感激!
这是在 Java 中完成的。
import java.util.*;
class Solution {
public int solution(int N) {
// write your code in Java SE 8
String binary = "";
int power = 31;
//double expo = Math.pow(2,power);
while(power !=-1){
if(N - Math.pow(2,power) > -1){
binary += "1";
N -= Math.pow(2,power);
}
else{binary += "0";}
power--;
}
System.out.println(binary);
//above works
int gap = 0;
int zero_count = 0;
int index = 0;
for( int i = 0; i < binary.length(); i++){
if(binary.charAt(i) == '1'){
index= i+1;
while(binary.charAt(index) =='0'){
index++;
zero_count++;
if(index == binary.length()-1){
return 0;
}
}
}
if(zero_count > gap){
gap = zero_count;
zero_count = 0;
}
i = index;
}
return gap;
}
}
循环太多..
将 main 添加到 drive/run 代码;您可以删除方法上的静态。
import java.util.*;
class Solution {
public static void main(String[] args) {
System.out.println("the max gap is: "+ Solution.solution(103241));
}
public static int solution(int N) {
// write your code in Java SE 8
String binary = "";
int power = 31;
//double expo = Math.pow(2,power);
while(power !=-1){
if(N - Math.pow(2,power) > -1){
binary += "1";
N -= Math.pow(2,power);
}
else{binary += "0";}
power--;
}
System.out.println(binary);
//above works
int max_gap = 0;
int zero_count = 0;
int index = 0;
//boolean
for( int i = 0; i < binary.length(); i++){
if(binary.charAt(i) == '0') {
zero_count++;
}
else {
if (zero_count > max_gap){
max_gap = zero_count;
}
zero_count = 0;
}
}
return max_gap;
}
}
嵌套 while
循环中存在几个问题:
- 在比较
index
处的字符时应检查binary
的长度以避免StringOutOfBoundsException
- 到达字符串末尾时不应 return
0
- 结果可能不正确 index
应该在离开while
循环时递减- 前导
0
s 应该完全跳过以避免无限循环 此外,构建binary
string: 也存在问题
- 它不能正确转换负数 也就是说,以下代码解决了上述问题:
public static int solution(int N) {
// write your code in Java SE 8
String binary = "";
if (N == 0) {
binary = "0"; // shortcut for 0
} else {
N &= Integer.MAX_VALUE; // remove sign bit for negative numbers
while(N != 0) {
binary = (N & 1) + binary; // get rid of leading zeros
N >>= 1;
}
}
//above works
int gap = 0;
int zero_count = 0;
for (int i = 0, len = binary.length(); i < len; i++) {
if (binary.charAt(i) == '1') {
i++;
while (i < len && binary.charAt(i) == '0') {
zero_count++;
if (i == len - 1) {
zero_count = 0;
}
i++;
}
i--;
}
if (zero_count > gap) {
gap = zero_count;
zero_count = 0;
}
}
return gap;
}
但是,可以使用 Java 8 中可用的以下工具来实施更简单的解决方案:
Integer::toBinaryString
获取不带前导零的二进制字符串String::replaceAll
删除尾随零Pattern::splitAsStream
将剩余的字符串除以1
并得到Stream<String>
- common Stream API
mapToInt
,max
获取仅由零组成的子串的最大长度:
static int maxZeroGap(int n) {
return Pattern.compile("1")
.splitAsStream(
Integer.toBinaryString(n).replaceAll("0+$", "")
)
.mapToInt(String::length)
.max()
.orElse(0);
}
测试:
int[] nums = {
0, 1, -1, -1023, Integer.MIN_VALUE, 0b10, 0b11, 0b101, 0b1001, 0b100101, 0b101000, 0b1000000100001
};
for (int i : nums) {
System.out.printf("%d -> %s%n", i, Integer.toBinaryString(i));
int z = maxZeroGap(i);
System.out.println("max zeros = " + z + "; solution=" + solution(i));
System.out.println("--------------------");
}
输出
0 -> 0
max zeros = 0; solution=0
--------------------
1 -> 1
max zeros = 0; solution=0
--------------------
-1 -> 11111111111111111111111111111111
max zeros = 0; solution=0
--------------------
-1023 -> 11111111111111111111110000000001
max zeros = 9; solution=9
--------------------
-2147483648 -> 10000000000000000000000000000000
max zeros = 0; solution=0
--------------------
2 -> 10
max zeros = 0; solution=0
--------------------
3 -> 11
max zeros = 0; solution=0
--------------------
5 -> 101
max zeros = 1; solution=1
--------------------
9 -> 1001
max zeros = 2; solution=2
--------------------
37 -> 100101
max zeros = 2; solution=2
--------------------
40 -> 101000
max zeros = 1; solution=1
--------------------
4129 -> 1000000100001
max zeros = 6; solution=6
--------------------