给定一个long型常量,其值为x,给定long型变量a,要求a & x 的取值集合
给定一个long型常量,其值为x,给定long型变量a,要求a & x 的取值集合,结果放入ArrayList中。
思路,x先转换为bit数组,得出其中元素值为1的总数为n,则所有取值的总数为2的n次方,记为N。
在0~N的闭区间中,依次取出各个数值,记为tmp,将tmp也转换为bit数组,依次遍历x的每一个bit位,当x的bit位为1时,到tmp中去取出相应的bit位,如果也为1,则将该位为1时,其他所有位为0时所代表的数值累加到结果中。
遍历完所有的bit位后,得到的结果即为所需要的数值。
整个思路有点复杂,性能也不高,从数值本身的与或运算上面着手,肯定还有更简单的方法。
代码:
package test.bit.ops;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class TestMain
{
public static void main(String[] args)
{
final long maxvalue = Long.MAX_VALUE;
long x = 58;
if (x > maxvalue)
{
x = x & maxvalue;
}
Set<Long> aset = new TreeSet<Long>();
for (long i = 0; i <= x; i++)
{
aset.add(i & x);
}
System.out.println(aset);
aset = null;
List<Long> resList = new ArrayList<Long>();
byte[] bitArray = long2BinaryArray(x);
long max = 0;
int j = 0;
for (int i = 0; i != bitArray.length; i++)
{
if (bitArray[i] == '1')
{
max += Math.pow(2, j);
j++;
}
}
int maxlength = bitArray.length;
for (long i = 0; i <= max; i++)
{
long result = 0;
byte[] tmp = long2BinaryArray(i);
int ltmp = tmp.length;
for (int s = maxlength - 1; s >= 0; s--)
{
if (bitArray[s] == '1')
{
if (ltmp <= 0)
{
break;
}
else
{
ltmp--;
if (tmp[ltmp] == '1')
{
result += Math.pow(2, maxlength - 1 - s);
}
}
}
}
resList.add(result);
}
System.out.println(resList + " : " + resList.size());
}
private static byte[] long2BinaryArray(long num)
{
String binaryString = Long.toBinaryString(num);
byte[] bitArray = binaryString.getBytes();
return bitArray;
}
}
运算结果:
[0, 2, 8, 10, 16, 18, 24, 26, 32, 34, 40, 42, 48, 50, 56, 58]
[0, 2, 8, 10, 16, 18, 24, 26, 32, 34, 40, 42, 48, 50, 56, 58]
5 条评论
赞,这样简单高效,我写的那个太烂了!
F:\Source_Code\myprogs\myprog\axproblem\Release>axproblem.exe 1132442325
consumed time: 187ms.
C++只用了187毫秒。呆会测试一下Java递归算法的耗时。
递归主要函数调用开销比较大, 用stack来模拟实现回溯,效率应该可以再提一些。 而且还不会有栈溢出的风险。