以二进制数计算最大连续数1

时间:2017-03-05 13:35:17

标签: java

如何在Java中计算二进制数最大连续1? 例如,用户输入类似13的整数,这将是二进制1101。 二进制数1101具有2个连续的1,因此输出应为2。 另一个例子,数字5将是二进制0101,因此输出应为1.如果我输入数字439,我的程序无法正常工作。

Scanner scanner = new Scanner(System.in);
        int numb = scanner.nextInt();
        int tempCount = 0;
        int count = 0; 

        // numb = 439 -> output 3
        // numb = 13  -> output 2
        // numb = 1   -> output 1 
        while (numb >= 1) {

            if (numb % 2 != 0) {

                tempCount++;
                numb /= 2;
                count = tempCount;
                if (numb % 2 != 0) {
                    tempCount++;
                    count = tempCount;
                    numb /= 2;
                }

            }
            else {
                numb /= 2;
                tempCount = 0;
            }
        }
        System.out.println(count);

4 个答案:

答案 0 :(得分:1)

我明白了,这是解决方案。 我忘记了嵌套的if语句。

Scanner scanner = new Scanner(System.in);
int numb = scanner.nextInt();
int tempCount = 0; //save temporarily the longest sequence of one's in this variable 
int count = 0; // before the sequence of one's gets interrupted, I save the value from tempCount in count

// numb = 439 -> output 3
// numb = 13  -> output 2
// numb = 1   -> output 1 
while (numb >= 1) {

    if (numb % 2 != 0) {

        tempCount++;
        numb /= 2;
        if(count < tempCount){
            count = tempCount;
        }

    }
    else {
        numb /= 2;
        tempCount = 0;
    }
}
System.out.println(count);

答案 1 :(得分:1)

我们可以在最不重要的位置识别两个连续的二进制位,如下所示:

(value & 0b11) == 0b11

我们可以将值向右移动,如下所示:

value >>>= 1;

使用tripple >>>>>更重要是因为我们不关心标志位。

然后我们要做的就是跟踪连续1的最大数量:

int countMax1Streak(int value) { // value could also be a long if required
    int max = 0;
    int count = 1;
    while (value != 0) {
        if ((value & 0b11) == 0b11) {
            count++;
        } else {
            count = 1;
        }
        value >>>= 1;
        if (count > max) {
            max = count;
        }
    }
    return max;
}

测试用例:

assertEquals(0, countMax1Streak(0b0));
assertEquals(1, countMax1Streak(0b1));
assertEquals(1, countMax1Streak(0b10));
assertEquals(2, countMax1Streak(0b11));
assertEquals(3, countMax1Streak(0b1110011));
assertEquals(3, countMax1Streak(0b1100111));
assertEquals(3, countMax1Streak(0b1110111));
assertEquals(7, countMax1Streak(0b1111111));
assertEquals(32, countMax1Streak(-1));

您也可以使用这样计算最大0条纹:

public int countMax0Streak(int value) {
    return countMax1Streak(~value);
}

答案 2 :(得分:1)

我相信您希望count是1s中最长序列的长度,而tempCount是您当前计数的序列中1的数量。因此,如果tempCount大于count,则只应将count分配给tempCount。对于439,我相信你正确计算三个1。然后是0,你正确地将tempCount重置为零。下次计算1时,您正确地将count增加到1,然后将此值分配给public interface X<y extends Y<x extends X<y extends...>>> { Object getO(); } public interface Y<x extends X<y extends Y<x extends ....>>> { void doSomething(); } ,并且您的计数将丢失。

答案 3 :(得分:0)

这是一个有趣的问题。这是一个通用的解决方案,并且还考虑了所有long值(如果在Java中检查n的值,您的解决方案可能不适用于负数:

public class LongestBitStreak {

/**
 * Returns the longest <i>streak</i> of the given bit b in 
   given number n. 
 * A bit streak is defined as a consecutive sequence of the given bit. 
 * @param n the number to find streak in
 * @param b the bit whose streak is to be found
 * @return the <i>longest</i> bit streak
 */
static int get(long n, int b) {
    if (b != 0 && b != 1)
        throw new IllegalArgumentException("second arg: (" + b + ") must be 0 or 1");
    int streak = 0, maxStreak = 0;
    for (int i = 0; i < 64; i++) {
        if ((n & 1) == b) {
            streak += 1;
            maxStreak = Math.max(streak, maxStreak);
        } else {
            streak = 0;
        }
        n >>= 1;
    }
    return maxStreak;
}

}

这是一个有趣的单元测试:

@Test
public void foolProof() {
    long n = 0b11111000001111100110101010;
    long nc = ~n; // One's complement of n
    System.out.println(get(n, 1));
    System.out.println(get(nc, 0));
    assertEquals(get(n, 1), get(nc, 0));
    assertEquals(get(n, 0), get(nc, 1));
}

请注意,根据数字和位的值可以进行一些优化,但对于初学者来说这应该是一个不错的解决方案。