查找数字中连续一位的最大数量(Java)
这实际上是我在书中发现的一个问题。问题是找到一个数字中连续一位的最大数量 例如:查找数字中连续一位的最大数量(Java),java,algorithm,performance,math,bit,Java,Algorithm,Performance,Math,Bit,这实际上是我在书中发现的一个问题。问题是找到一个数字中连续一位的最大数量 例如: 数字123(01111011基数2)应输出“4”(011110){ in=(in&(in您可以将您的递归转换为以获得增强的性能。它对于堆栈使用更节省。如果您不知道尾部递归的含义,请阅读前面的链接 public class ConsecutiveOnes { public static void main(String[] args) { long num = 123;
数字123(01111011基数2)应输出“4”(0
1111
<011)
我想找到最有效、最紧凑的算法来实现这一点
这是我最好的机会:
int getMaxBits(long number) {
return number != 0 ? getMaxBits(number & (number >>> 1)) + 1 : 0;
}
这对小数字非常有效。但由于它可以递归调用它自己多达63次,我认为这不是最有效的方法
我知道,迭代显然效率更高,因为Java编译器不会在没有尾部递归的情况下优化递归。我只是喜欢这样,我可以把它写在一行。真正的问题是,是否有比计算班次更有效的方法?正如Shawn Chin在中所描述的,这是Java的一个端口:
public static void count_consecutive_ones(int in) {
int count = 0;
while (in>0) {
in = (in & (in << 1));
count++;
}
System.out.println(count);
}
public static void main(String[] args) {
count_consecutive_ones(15);
}
公共静态无效计数\u连续\u个(整数英寸){
整数计数=0;
while(in>0){
in=(in&(in您可以将您的递归转换为以获得增强的性能。它对于堆栈使用更节省。如果您不知道尾部递归的含义,请阅读前面的链接
public class ConsecutiveOnes
{
public static void main(String[] args)
{
long num = 123;
System.out.println(num + " has " + getMaxBits(num) + " consecutive 1's");
}
public static int GetMaxBits(long number)
{
return accGetMaxBits(number, 0);
}
private static int accGetMaxBits(long number, int accum)
{
if( number == 0 ) return accum;
accum += 1;
return accGetMaxBits(number & (number >>> 1), accum);
}
}
尝试使用-1
(长),即0xFFFFFFFF
,然后将尾部版本与您的版本进行比较
long num = 0xFFFFFFFF;
System.out.println(num + " has " + accGetMaxBits(num) + " consecutive 1's");
// Out: -1 has 64 consecutive 1's
这里有一个明确的方法,即可能有一个更紧凑/高效的实现,但至少可以更直观地理解
count = 0
max = 0
while n > 0
if first bit (from the right) is 1
increment count
else
if count > max
max = count
reset count back to 0
set n equal to itself right-shifted over 1
return max
在java中:
static int countBits(int n){
int max=0;
整数计数=0;
而(n>0){
如果((n&1)=1)计数++;
否则{
如果(计数>最大值)最大值=计数;
计数=0;
}
如果(计数>最大值)最大值=计数;
n=n>>1;
}
返回最大值;
}
公共静态void main(字符串[]args){
int n=0B1110001111;
系统输出println(countBits(n));
}
输出:
4
BitSet bitSet = BitSet.valueOf(new long[] {123});
int count = 0;
int max = 0;
for (int i=0; i < bitSet.size(); i++) {
if(bitSet.get(i)) {
count++;
} else {
max = Math.max(max, count);
count = 0;
}
}
System.out.println(max);
从表面上看,我的解决方案是丢失的,但如果你有真正的大位数组,它的大小比long的大
p、 欢迎关注代码。不要使用递归和循环方法?如果递归方法不够优雅,请将其更改为迭代方法。如果long是64位,为什么最大迭代次数不是64?在C中,您可以在(数字&=number-FYI:Hacker's Delight,第二版,第6-3节是关于这个主题的,包含了一些关于这个和相关问题的非常有趣的算法。这个问题是用Java编译的吗?你应该只注释它(链接)/标记为重复then@Bathsheba由于while(在中)而不会
@Bathsheba no,因为它正在将布尔值转换为long,而我现在没有给出原因。对你和我来说,性能差异很大(即-1(long))。@nickzoum在给出否决票时,请说明原因,不要表现得像个傻瓜,我看起来像个新手吗?(没有否决票(但:),但是:这是如何回答的[是否有比计算班次更有效的方法?
)我昨天编辑了这个问题。跟踪问题的天数(添加真正的问题是,是否有比计算班次更有效的方法?
是由nick zoum提出的。)(这是如何回答[是否有]一种比计算移位更有效的方法?
(问题中的方法:#在最长时间内,而不是像这个答案那样的ld(n)(最高有效位的位置))我的基本假设,以及评论中的一些建议,是,一般来说,迭代解决方案比递归解决方案更有效,因为在递归中,你必须记住以前的函数输入等。而迭代不是这样。所以我的答案,因为它是迭代的,与OP相比,OP是递归的ve可能“更有效”
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(1)
@State(Scope.Benchmark)
public class MyBenchmark {
@Param({"0", "1", "255", "4294967295", "-1"})
public long value;
@Benchmark
public int testBitSet() {
int count = 0;
int max = 0;
BitSet bitSet = BitSet.valueOf(new long[]{value});
for (int i = 0; i < bitSet.size(); i++) {
if (bitSet.get(i)) {
count++;
} else {
max = Math.max(max, count);
count = 0;
}
}
return max;
}
@Benchmark
public int testBitWiseOperation() {
int max = 0;
int count = 0;
while (value > 0) {
if ((value & 1) == 1) count++;
else {
if (count > max) max = count;
count = 0;
}
if (count > max) max = count;
value = value >> 1;
}
return max;
}
@Benchmark
public int testRecursion() {
return getMaxBits(value);
}
public static int getMaxBits(long number) {
return accGetMaxBits(number, 0);
}
private static int accGetMaxBits(long number, int accum) {
if (number == 0) return accum;
accum += 1;
return accGetMaxBits(number & (number >>> 1), accum);
}
}
# Run complete. Total time: 00:03:49
Benchmark (value) Mode Cnt Score Error Units
MyBenchmark.testBitSet 0 avgt 5 3,570 ? 0,019 ns/op
MyBenchmark.testBitSet 1 avgt 5 84,515 ? 2,188 ns/op
MyBenchmark.testBitSet 255 avgt 5 85,238 ? 0,581 ns/op
MyBenchmark.testBitSet 4294967295 avgt 5 80,629 ? 0,816 ns/op
MyBenchmark.testBitSet -1 avgt 5 66,905 ? 1,446 ns/op
MyBenchmark.testBitWiseOperation 0 avgt 5 2,200 ? 0,297 ns/op
MyBenchmark.testBitWiseOperation 1 avgt 5 2,164 ? 0,011 ns/op
MyBenchmark.testBitWiseOperation 255 avgt 5 2,166 ? 0,030 ns/op
MyBenchmark.testBitWiseOperation 4294967295 avgt 5 2,172 ? 0,047 ns/op
MyBenchmark.testBitWiseOperation -1 avgt 5 2,164 ? 0,028 ns/op
MyBenchmark.testRecursion 0 avgt 5 2,171 ? 0,015 ns/op
MyBenchmark.testRecursion 1 avgt 5 2,460 ? 0,029 ns/op
MyBenchmark.testRecursion 255 avgt 5 9,546 ? 0,090 ns/op
MyBenchmark.testRecursion 4294967295 avgt 5 31,357 ? 0,389 ns/op
MyBenchmark.testRecursion -1 avgt 5 66,708 ? 0,349 ns/op