我正在尝试创建一个快速生成特定序列的程序。
序列通过迭代给出,如下:
new = old + 1 + (-1*(old reversed))
示例:
old = [1]
new = [1]+[1]+[-1] = [1, 1, -1]
old = [1, 1, -1]
new = [1, 1, -1] + [1] + [1, -1, -1] = [1, 1, -1, 1, 1, -1, -1]
我希望这个尽可能快,我想由于序列只包含-1或1,我可以使用按位运算,让每个位代表true
或false
然后,我可以将其映射到-1
或1
。
然后我最终得到一系列位,我可以使用按位运算来操作。我有一个自定义类,它创建一个long[]
,然后将这些位组合成64位。
一切正常,我得到了正确的答案,但这个解决方案要比使用byte[]
数组和循环槽慢得多。
最耗时的功能是反转位的顺序,并反转每一位。
现在看起来像:
//this function is inside the custom class I defined
public void set(int n, int d) { //set bit n as the inverse value of bit d
storage[n/64] ^= ~(storage[ind/64] & (1L << ind)) << (n-ind);
}
//sequence is an instance of my custom class
//the length of the sequence is sequenceLength
for (int i = 1; i < sequenceLength; i++) {
sequence.set(sequenceLength+i, sequenceLength-i);
}
有什么方法可以提高性能吗?我对按位操作很新。
编辑:这是包含所有相关方法的自定义类。
public class Dragon3 {
private FastStorage dragon;
private short[] xpos;
private short[] ypos;
public Dragon3(int n) {
dragon = new FastStorage((int)Math.pow(2,n+1)-1);
dragon.setSize(1);
for (int i = 0; i < n; i++) {
iterate(dragon);
}
}
public class FastStorage {
private long[] storage;
private int size;
public FastStorage(int n) {
storage = new long[(n-1)/64+1];
size = n;
}
public int getSize() {
return size;
}
public void setSize(int n) {
size = n;
}
public void set(int n, int ind) {
storage[n/64] ^= (~storage[ind/64] & (1L << ind)) << (n-ind);
}
public long getInv(int n) {
return ~(storage[n/64]) & (1L << n);
}
public void iterate(FastStorage drag) {
int dragLength = drag.getSize();
drag.setSize(2*dragLength+1);
//drag.toggle(dragLength);
for (int i = 1; i < dragLength+1; i++) {
drag.set2(dragLength+i, dragLength-i);
//drag.set(dragLength+i, drag.getInv(dragLength-i));
}
}
public static void main(String[] args) {
Dragon3 instance = new Dragon3(Integer.valueOf(args[0]));
}
}
答案 0 :(得分:2)
你没有要求它,但你的序列有一个直接的公式:
public static void main(String[] args) {
for( int n=1 ; n<=15 ; n++ ){
int fold = 1 - ((n/(n&-n))&2);
System.out.print(" " + fold);
}
System.out.println();
}
答案 1 :(得分:0)
您可以尝试使用BitSet,但它通常会跟踪设置的位,因此您可能需要跟踪您感兴趣的位数:
public static void main(String[] args) {
BitSet bitSet = new BitSet();
bitSet.set(0,true);
bitSet.set(1, true);
bitSet.set(2, false);
final int length = 3;
printBitSet(bitSet, length);
BitSet newBitSet = new BitSet(length * 2 + 1);
for (int i = 0; i <length; i++) {
newBitSet.set(i, bitSet.get(i));
}
newBitSet.set(length, true);
for (int i = 0; i < length; i++) {
newBitSet.set(length + i + 1, !bitSet.get(length - i - 1));
}
printBitSet(newBitSet, 2*length +1);
}
private static void printBitSet(BitSet bitSet, int length) {
for (int i = 0; i < length; i++) {
System.out.print(" " +( bitSet.get(i) ? "1" : "-1"));
}
System.out.println();
}