如何在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);
答案 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));
}
请注意,根据数字和位的值可以进行一些优化,但对于初学者来说这应该是一个不错的解决方案。