Java 计算二进制间隙时的无限while循环

Java 计算二进制间隙时的无限while循环,java,infinite-loop,Java,Infinite Loop,我目前正在解决二进制间隙问题(计算两个1之间的0的数量,并返回找到的0的最大间隙),我的解决方案首先从将整数N转换为N的二进制形式的字符串开始,这很好 从概念上讲,我正在做的(或者至少我认为我正在做的)是计算0,直到我达到一个1字符,然后将其与变量gap下的当前0计数进行比较,然后我将我的零计数器zero\u count,我还添加了一个if语句来检查它是否到达二进制字符串的末尾,如果没有返回0,如果找到则返回1 出于某种原因,我得到了一个无限循环,我想我已经把它缩小到了索引值不增加的范围,我不知

我目前正在解决二进制间隙问题(计算两个1之间的0的数量,并返回找到的0的最大间隙),我的解决方案首先从将整数N转换为N的二进制形式的字符串开始,这很好

从概念上讲,我正在做的(或者至少我认为我正在做的)是计算0,直到我达到一个1字符,然后将其与变量
gap
下的当前0计数进行比较,然后我将我的零计数器
zero\u count
,我还添加了一个if语句来检查它是否到达二进制字符串的末尾,如果没有返回0,如果找到则返回1

出于某种原因,我得到了一个无限循环,我想我已经把它缩小到了索引值不增加的范围,我不知道为什么。如果有人能解释,我将不胜感激

这是用Java实现的

import java.util.*;
类解决方案{
公共int解决方案(int N){
//用JavaSE8编写代码
字符串binary=“”;
整数幂=31;
//双博览会=数学功率(2,功率);
while(电源!=-1){
if(N-数学功率(2,功率)>-1){
二进制+=“1”;
N-=数学功率(2,功率);
}
else{binary+=“0”;}
权力--;
}
System.out.println(二进制);
//以上作品
int-gap=0;
int zero_count=0;
int指数=0;
对于(int i=0;i间隙){
间隙=零计数;
零计数=0;
}
i=指数;
}
返回间隙;
}
}
循环太多

添加main来驱动/运行代码;您可以删除该方法上的静态

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;
    }
}
import java.util.*;
类解决方案{
公共静态void main(字符串[]args){
System.out.println(“最大间隙为:“+Solution.Solution(103241));
}
公共静态int解决方案(int N){
//用JavaSE8编写代码
字符串binary=“”;
整数幂=31;
//双博览会=数学功率(2,功率);
while(电源!=-1){
if(N-数学功率(2,功率)>-1){
二进制+=“1”;
N-=数学功率(2,功率);
}
else{binary+=“0”;}
权力--;
}
System.out.println(二进制);
//以上作品
int max_gap=0;
int zero_count=0;
int指数=0;
//布尔值
对于(int i=0;i最大间隙){
最大间隙=零计数;
}
零计数=0;
}           
}
返回最大间隙;
}
}

嵌套的
while
循环中有几个问题:

  • 在比较
    索引
    处的字符时,应检查
    二进制
    的长度,以避免
    StringOutOfBoundsException
  • 当到达字符串末尾时,它不应返回
    0
    ——结果可能不正确
  • 退出
    while
    循环时,应减小
    索引
  • 应完全跳过前导
    0
    s,以避免无限循环 此外,构建
    binary
    string也存在问题:
  • 它不能正确地转换负数 尽管如此,以下代码解决了上述问题:
公共静态int解决方案(int N){
//用JavaSE8编写代码
字符串binary=“”;
如果(N==0){
binary=“0”//0的快捷方式
}否则{
N&=Integer.MAX_VALUE;//删除负数的符号位
而(N!=0){
二进制=(N&1)+二进制;//去掉前导零
N>>=1;
}
}
//以上作品
int-gap=0;
int zero_count=0;
for(int i=0,len=binary.length();i间隙){
间隙=零计数;
零计数=0;
}
}
返回间隙;
}
但是,可以使用Java 8中提供的以下工具实现更简单的解决方案:

  • Integer::toBinaryString
    获取不带前导零的二进制字符串
  • String::replaceAll
    删除尾随零
  • Pattern::splitAsStream
    将剩余字符串按
    1
    拆分,并获取
    Stream
  • 公共流API
    mapToInt
    max
    获取仅由零组成的子字符串的最大长度:
static int maxZeroGap(int n){
返回模式。编译(“1”)
.分流(
Integer.tobinarysting(n).replaceAll(“0+$”,“”)
)
.mapToInt(字符串::长度)
.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
--------------------

31的二进制是0001111,因此您可以忽略
if(binary.charAt(i)='1')
if(zero\u count>gap)
,现在想想:您的循环会退出吗?那你就会明白问题了。我现在看到了错误,但还有一个问题,但我仍然对自己的想法感到困惑