【问题标题】:Binary Gap Program in JavaJava中的二进制间隙程序
【发布时间】:2019-03-14 20:02:12
【问题描述】:

我的问题陈述:

正整数 N 中的二进制间隙是在 N 的二进制表示中两端被 1 包围的连续零的任何最大序列。例如,数字 9 的二进制表示为 1001,包含长度为 2 的二进制间隙. 数字 529 具有二进制表示 1000010001 并包含两个二进制间隙:一个长度为 4 和一个长度为 3。数字 20 具有二进制表示 10100 并包含一个长度为 1 的二进制间隙。数字 15 具有二进制表示 1111 并且没有二进制间隙。数字 32 具有二进制表示 100000 并且没有二进制间隙。

我的代码:

public class Abc {

    static void decToBinary(int n) {

        int[] binaryNum = new int[1000];

        // counter for binary array 
        int i = 0;
        while (n > 0) {
            // storing remainder in binary array 
            binaryNum[i] = n % 2;
            n = n / 2;
            i++;
        }
        int ctr = 0, k = 0;
        ArrayList<Integer> al = new ArrayList<Integer>();

        // printing binary array in reverse order 
        for (int j = i - 1; j >= 0; j--) {
            System.out.print(binaryNum[j]);
            if (binaryNum[j] == 0) {
                k = j;
                do {
                    ctr++;
                    k++;
                } while (binaryNum[k] == 0);
                al.add(ctr);
                ctr = 0;
            }
        }

        for (int ii = 0; ii < al.size(); ii++) {
            System.out.println(al.get(ii));
        }
    }

    // driver program 
    public static void main(String[] args) {
        int n = 1041;
        decToBinary(n);
    }
}

我正在尝试显示存储在我的 ArrayList 中的二进制间隙的输出。但是对于给定的输入 1041,输出是完全不同的。我不知道它为什么要存储 1、2、3、4;根据我的逻辑,在输入:1041 的情况下,它应该只存储间隙值 5 和 3,即使 5 和 3 也存储在 ArrayList 中但在其他一些索引中。

我认为 do-while 循环中存在问题,尤其是在 al.add(ctr) 中,但我还没有弄清楚。

【问题讨论】:

  • 代码应该做什么? “问题陈述”没有定义任何行为,它只定义了“二进制间隙”是什么。 if 的任务是否存在二元差距?二进制间隙的数量? 最长二元间隙?最长二进制间隙的长度?还有什么?
  • @Bohemian 我认为你没有仔细阅读声明并运行代码。
  • 问题不清楚。问题陈述说明了什么 差距是什么,但没有说明找到的差距做什么。如果您不知道它应该做什么,那么该代码是无关紧要的。顺便说一句,可能有一个 1 行解决方案。
  • 问题陈述中的什么地方说要打印任何东西?事实上,问题陈述并没有说要做什么,它只是定义了什么二元间隙是什么,而不是当你找到一个时要做什么。
  • @makoto 哎呀——我是想问 Ameeq

标签: java loops arraylist


【解决方案1】:

如果这是家庭作业,你的问题就在这里:

    for (int j = i - 1; j >= 0; j--) {
        if (binaryNum[j] == 0) {
            k = j;
            do {
                ctr++;
                k++;
            } while (binaryNum[k] == 0);
            al.add(ctr);
            ctr = 0;
        }
    }

注意:

  • 您会在进行过程中更新k,但您不会更新j,因此无论正确的值是多少([1, 2, 3, 4, 5, 1, 2, 3] 而不是[5, 3])都会得到 1。
  • 你根本不需要k。
    for (int j = i - 1; j >= 0; j--) {
        if (binaryNum[j] == 0) {
            int ctr = 0;
            while (binaryNum[j] == 0) {
                ctr++;
                j--;
            }
            al.add(ctr);
        }
    }

这是shown to work here。


如果您不是为了家庭作业而这样做,并且您需要性能以供实际使用,请使用 the Integer class 中的 Java 内置按位方法,它在具有它们的 CPU 上使用非常非常快的 CPU 指令:

import java.util.Arrays;

public class Abc {
    public static final int[] gaps(int n) {
        // The number of gaps is the number of one bits minus one.
        final int[] result = new int[Math.max(0, Integer.bitCount(n) - 1)];
        
        // Remove the last one bit and all bits after to get to first gap.
        n >>>= Integer.numberOfTrailingZeros(n) + 1;
        
        for (int i = result.length - 1; i >= 0; i--) {
            final int gapSize = Integer.numberOfTrailingZeros(n);
            result[i] = gapSize;
            // Remove the last one bit and all bits after to get to next gap.
            n >>>= gapSize + 1;
        }
        
        return result;
    }
    
    // Driver program 
    public static void main(final String[] args) {
        final int n = 1041;
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Arrays.toString(gaps(n)));
    }
}

这是shown to work here。

【讨论】:

  • 那么什么是实际使用的最佳解决方案?
  • @AmeeqHanzlahSohail 抱歉,我的代码有一个小的负数错误已修复(现在使用&gt;&gt;&gt;= 代替&gt;&gt;=),如果您看到代码中包含&gt;&gt;=,请刷新。如果需要,您可以使用ArrayLists 代替数组,只需在应用程序中测试两者的速度即可。如果您只需要打印间隙,则根本不需要数组即可。只需System.out.println(gapSize); 而不是数组赋值。
  • 得到了你的最后一个声明,但没有这个">>="谢谢你的回答!!!
【解决方案2】:

下面的解决方案给了我 100%:

class Solution {
        public int solution(int N) {
            String value = Integer.toBinaryString(N);
            int counter = 0;
            List<Integer> counters = new ArrayList<>();
            for (int i = 0; i < value.length(); i++) {
                char current = value.charAt(i);
                if (current == '0') {
                    counter += 1;
                } else {
                    counters.add(counter);
                    counter = 0;
                }
            }
            return Collections.max(counters);
        }
    }

【讨论】:

    【解决方案3】:

    var k 也应该减少,因为 j 减少了,在迭代完成后你应该分配 j = k。并且您必须检查 k 是否大于或等于零while (k &gt;= 0 &amp;&amp; binaryNum[k] == 0);,否则您会得到 ArrayIndexOutOfBoundsException。您还必须检查 k 是否小于零才能正确计算二进制间隙if(k &lt; 0) {j = k;break;}

      for (int j = i - 1; j >= 0; j--) {
            System.out.print(binaryNum[j]);
            if (binaryNum[j] == 0) {
                k = j;
                do {
                    ctr++;
                    k--;
                } while (k >= 0 && binaryNum[k] == 0);
                if(k < 0) {
                    j = k;
                    break;
                }
                al.add(ctr);
                ctr = 0;
                j = k;
            }
        }
    

    【讨论】:

      【解决方案4】:

      这个答案我得到了满分 100 分。希望这会帮助你。

      public int solution(int N) {
              String binary = Integer.toBinaryString(N);
              int count = 0;
              int tmpCount = 0;
              for (int i = 0; i < binary.length(); i++) {
                  if (binary.charAt(i) == '0') {
                      if (i > 0 && binary.charAt(i - 1) == '1') {
                          tmpCount++;
                      } else {
                          if (tmpCount > 0) tmpCount++;
                      }
                  } else if (binary.charAt(i) == '1') {
                      if (tmpCount > 0 && tmpCount > count) {
                          count = tmpCount;
                      }
                      tmpCount = 0;
                  }
              }
              return count;
          }
      

      【讨论】:

        【解决方案5】:

        //100% 处理所有测试用例

        public static void main(String ar[]) {
                Integer val = 10092;
                String vals = val.toBinaryString(val);
                int gapVal = findBinaryGap(vals);
                System.out.println(vals);
                System.out.println("gapVal=" + gapVal);
        
            }
        
        public static Integer findBinaryGap(String binVal) {
                Integer retVal = 0;
                String splitVal[] = binVal.split("1");
                int endVal = splitVal.length;
                if (binVal.endsWith("0")) {
                    endVal = endVal - 1;
                }
                for (int incr = 0; incr < endVal; incr++) {
                    if (retVal < splitVal[incr].length()) {
                        retVal = splitVal[incr].length();
                    }
                }
                return retVal;
            }
        

        【讨论】:

          【解决方案6】:

          试试下面的代码,

          public int solution(int n) {
              String binaryString = Integer.toBinaryString(n);
              int count = 0, bigGap = 0, temptCount = 0;
              for (int i = 0; i < binaryString.length(); i++) {
                  char c = binaryString.charAt(i);
                  if (c == '0') {
                      temptCount++;
                  } else {
                      count = temptCount;
          
                      if (count > bigGap) {
                          bigGap = count;
                      }
                      temptCount = 0;
                  }
          
              }
          
              return bigGap;
          }
          

          【讨论】:

            【解决方案7】:

            试试这个,我得到了 100%

            public int solution(int N) {
                String binaryNumber = Integer.toBinaryString(N);
            
                String[] gaps = binaryNumber.replaceAll("0+$", "").split("1");
            
            
                int maxLength = 0;
                for (String gap: gaps) {
                    if (gap.length() > 0 && gap.length() > maxLength) {
                        maxLength = gap.length();
                    }
                }
                return maxLength;
            }
            

            【讨论】:

              【解决方案8】:

              我的解决方案 100%

              public class Solution {
              public int solution( int N ){
              
                  String rep = "";
                  String[] zoros = null;
                  int maxi = 0;
              
                  try{
                      if( N < 5 ){ return maxi; } // 5 is the first positive integer that contains a bi-gap
              
                      rep = Integer.toBinaryString(N);
                      zoros = rep.split("1");
              
                      // deal with edges
                      if(!rep.startsWith("1")){ zoros[0] = ""; }
                      if(!rep.endsWith("1")){ zoros[zoros.length - 1] = "";}
                      
                      //now looper
                      for( int i = 0; i < zoros.length ;i++ ){
                          if(zoros[i].length() > maxi){
                              maxi = zoros[i].length();
                          }
                      }
                  } 
                  catch( Exception e ){ 
                      System.console().writer().println(e.getMessage()); 
                  }
                  System.console().writer().println("Neo-Maxi Zoomdweebie: " + Integer.toString(maxi));
                  return maxi;
              }
              }
              

              【讨论】:

              • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关how to write good answers 的更多信息。
              【解决方案9】:

              关于 codility,我对 BinaryGap“问题”的解决方案是

              public int solution(int N) {
                      //get binary representation
                      String binaryRep = Integer.toBinaryString(N);
                      //cut last zeros since they aren't between "1"
                      if (!binaryRep.endsWith("1")) {
                          final int i = binaryRep.lastIndexOf("1");
                          binaryRep = binaryRep.substring(0, i);
                      }
              
                      //count the longest zero string
                      String[] binaryBlocks = binaryRep.split("1");
                      int result = 0;
                      for (String binaryBlock : binaryBlocks) {
                          int binaryBlockLength = binaryBlock.length();
                          if (binaryBlockLength > result) {
                              result = binaryBlockLength;
                          }
                      }
                      return result;
                  }
              

              希望对您有所帮助! :)

              【讨论】:

                【解决方案10】:
                public int solution(int N){
                    try {
                        return Collections.max(Arrays.asList(Integer.toBinaryString(N)
                                .replaceAll("0+$", "").split("1"))
                                .stream().mapToInt(String::length).boxed()
                                .collect(Collectors.toList()));
                    }catch (NoSuchElementException e){
                        return 0;
                    }
                }
                

                "0+$" - replacing all trailing zeros
                

                【讨论】:

                  【解决方案11】:

                  这个解决方案给了我 100% 的分数,我使用 indexOf 得到第一个索引 1,然后得到第一个第二个索引 1 并计算它们之间的差异,这给了我一个 0 的子字符串,保存它的长度子字符串,然后像我们之前一样计算第二个 0 的子字符串,因此,每次计算子字符串时,请确保选择最长的子字符串。

                  class Solution {
                      public int solution(int N) {
                          String bin = intToBinary(N);
                          int firstOne = bin.indexOf('1');
                          int cnt = 0;
                          
                          for(int i=firstOne; i<bin.length(); ++i){
                              int sec = bin.indexOf('1', i);
                              cnt = Math.max(sec-firstOne-1, cnt);
                              firstOne = sec;
                          }
                          return cnt;
                          
                      }
                      
                      private static String intToBinary(int N){
                          String s = "";
                          while(N>0){
                              s = ( (N%2) == 0 ? "0" : "1") + s;
                              N = N / 2;
                          }
                          return s;
                      }
                  }
                  

                  【讨论】:

                    【解决方案12】:

                    这是最容易理解的 IMO

                    class Solution {
                        public int solution(int N) {
                            int gapSize = 0;
                            int tempCount = 0;
                            String s = Integer.toBinaryString(N);
                    
                    /* You can start the loop from index 1, since all binary numbers
                    except 0 start with 1 and 0 is covered by initializing the variables (saves 2 conditions) */
                            for(int i = 1; i < s.length(); i++) {
                                if(s.charAt(i) == '0') {
                                    tempCount++; // count the number of 0
                                } else if(s.charAt(i) == '1') {  // when 1 is found
                                    if(tempCount > gapSize) {    // and gap is smaller than the now measured one
                                        gapSize = tempCount;     // record the so far biggest gap
                                    }
                                    tempCount = 0;               // reset the counter when 1 is found
                                }
                            }
                            return gapSize;
                         }
                    } 
                    

                    【讨论】:

                      【解决方案13】:

                      顺便说一下,这是KOTLIN中的相应解决方案,如果有人感兴趣的话。

                      我首先将 Number 转换为 Binary String ,然后将 binary String 转换为 char Array ,然后循环 forEachIndexed 循环并尝试找到 1 的索引并将它们保存在 oneIndicesArrayList 并检查 newGap ,如果 newGap 是 大于 maxGap ,否则我将 newGap 值分配给 maxGap maxGap 将保留旧值。这工作完美,得分是 100%。

                      fun solution(N: Int): Int {
                              // write your code in Kotlin
                              val binaryStr = toBinary(N)
                              val charArray = binaryStr.toCharArray()
                      
                      
                          var maxGap = 0
                          var oneIndicesArray = arrayListOf<Int>() 
                          charArray.forEachIndexed { index, element ->
                              
                              if(element == '1') {
                                  if(oneIndicesArray.isNotEmpty()) {
                                     val newGap =  (index - oneIndicesArray[oneIndicesArray.size - 1]) - 1
                                      if(newGap > maxGap) maxGap = newGap
                                  }
                                  oneIndicesArray.add(index)
                              }
                          }
                          return maxGap
                      }
                      
                      fun toBinary(decimalNumber: Int, binaryString: String = "") : String {
                          while (decimalNumber > 0) {
                              val temp = "${binaryString}${decimalNumber%2}"
                              return toBinary(decimalNumber/2, temp)
                          }
                          return binaryString.reversed()
                      }
                      

                      【讨论】:

                        【解决方案14】:

                        我在这一项上得到了 100% 的分数

                        fun solution(N: Int): Int {
                        // write your code in Kotlin
                        var maxNumber= 0
                        val binary= Integer.toBinaryString(N)
                        val split= binary.split("1")
                        val loop= if(binary.endsWith("1")) split.size else split.size-1
                        for (s in 0 until loop){
                            maxNumber=Integer.max(maxNumber, split[s].length)
                        }
                        return maxNumber
                        

                        }

                        【讨论】:

                          【解决方案15】:
                          public static int solution(int N) {
                              // write your code in Java SE 8
                              int result = 0;
                              int prev = 0;
                              int diff;
                              int length = (int)(Math.ceil(Math.log(N) / Math.log(2)));
                              int[] binary=new int[length];
                              for(int i = length-1;i > -1;i--,N /= 2) binary[i] = N % 2;
                              for(int i = 0;i < length;i++){
                                  if(binary[i] == 1){
                                      diff = i - prev;
                                      result = diff > 1 && diff > result ? diff - 1 : result;
                                      prev = i;
                                  }
                              }
                              return result;
                          }
                          

                          【讨论】:

                            【解决方案16】:
                            public int solution(int N) {
                             String binaryNo = Integer.toBinaryString(N);
                             int firstIndex = binaryNo.lastIndexOf("1");
                             int currentGap = 0;
                             int biggestGap = 0;
                             for (int i = firstIndex; i >= 0; i--) {
                              if (getNthDegit(binaryNo, i) == 0) {
                               currentGap++;
                              } else {
                               if (biggestGap < currentGap) {
                                biggestGap = currentGap;
                               }
                               currentGap = 0;
                              }
                             }
                             return biggestGap;
                            }
                            
                            public static int getNthDegit(String number, int position) {
                             String numberString = "" + number;
                             char c = numberString.charAt(position);
                             return Character.getNumericValue(c);
                            }
                            

                            【讨论】:

                              【解决方案17】:

                              Python 风格的解决方案,获得了 100% 的分数:

                              public static int solution(int N) {      
                                  List<String>result = Arrays.asList(Integer.toBinaryString(N).replace("0"," ").strip().split("1")); 
                                  if(!result.isEmpty()){
                                       return Collections.max(result.stream().map(String::length).collect(Collectors.toList()));
                                  }        
                                   return 0;   
                              }
                              

                              【讨论】:

                                【解决方案18】:

                                在 Codility 中通过了所有测试。

                                public class BinaryGap {
                                
                                  public static void main(String ar[]) {
                                   Integer val = 328;
                                
                                   int gapVal = findBinaryGap(val);
                                   System.out.println("gapVal=" + gapVal);
                                
                                 }
                                
                                 public static Integer findBinaryGap(Integer binVal) {
                                
                                  String values = Integer.toBinaryString(binVal);
                                  String[] splitVal = values.substring(0, values.lastIndexOf("1")).split("1");
                                
                                  if (Arrays.stream(splitVal).noneMatch(v -> v.length() > 0)) {
                                    return 0;
                                  }
                                
                                   return java.util.Arrays.stream(splitVal).mapToInt(String::length)
                                                       .max().orElse(0);
                                 }
                                
                                }
                                

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2018-08-03
                                  • 2016-06-02
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2017-04-25
                                  相关资源
                                  最近更新 更多