我有一个程序,我目前正在使用byte[]
布尔数组,即每个元素都是0
或1
。我想我应该尝试使用按位运算来加速程序。
我需要解决的一个问题如下。例如,让
long a = 5 = "00101"
(我不会在开头写下所有无趣的零)
long b = 24 = "10100"
。 (我不会在开头写下所有无趣的零)
我需要一个操作,O
说,aOb
占据a
为1
的位置,取b
的相应值连接它们,以便在这种情况下我们将
2 = "00010"
。 (我不会在开头写下所有无趣的零)
a 00101
O ↓ ↓ <- pick bits pointed by `1` in a
b 10100
↓ ↓
1 0 -> concatenate selected bits -> 10
编辑:
试图澄清:
好的,我们从左边或右边经过a
。如果我们遇到0
,我们什么也没有。如果我们计算1
,我们会将相应索引的值b
。例如,从左侧开始,我们不会对两个0
执行任何操作,然后我们找到1
,因此我们从1
获取相应的b
,我们找到另一个0
1}}在a
中并且什么都不做,然后我们在1
中找到另一个a
并从0
中取出相应的b
。
修改
另一种说法就是这样:向右移a
并读出值(这可能吗?)。如果是1
,我们会将b
向右移动,读取值,将其存储到结果变量r
并向右移动r
。如果是0
,我们会将b
转移到右侧,忘记值,不对r
执行任何操作。
编辑:
我会详细说明目的,试图澄清我想做的事情。我们有一组布尔变量(比如说5与我们的例子一致)。变量b
根据某些索引表示其状态的数组。变量1
中的a
代表我们系统中的布尔变量的索引,即我们示例中的2和4,这与某个布尔变量(比如第0个)有关。第2和第4个布尔变量的值构成与第0个变量关联的真值表的可能输入之一。
有什么建议吗?
编辑: 现在,我正在做的就是这个。假设我们有一个包含5个布尔变量的系统,索引为$ 0,1,2,3,4 $。假设第0个变量是第2个和第4个变量的函数,并且具有AND的真值表,即
2 | 4 |Output for 0
0 | 0 | 0
0 | 1 | 0
1 | 0 | 0
1 | 1 | 1
我总是以这种方式对表进行排序,所以我真的不需要表的左侧部分。该表的右侧部分实现为byte[]
数组。为了找到输出,我只是将输入读取的整数表示作为二进制数。例如。输入10
为2,因此我的输出是我的byte[]
数组中索引2处的值。为了找到输入,我需要系统当前状态的一部分,它对应于有问题的变量,即0。也就是说,我想要第二个和第四个变量的值,按顺序读取。
因此:
byte[] c = new byte[]{1,0,1,0,0}; //Corresponds to b above
int[] ind = new int[]{2,4}; //Indices of c that we're interested in
byte[] table = new byte[]{0,0,0,1}; //The truth table
int j = 0; //Truth table index
for(int i = 0; i < ind.length; i++) {
j += c[ind[i]]*(1 << (ind.length - 1 - i)) //Binary to integer
}
//Output is table[j]
答案 0 :(得分:3)
顺便说一下,“10100”是20而不是24
And the client requests with the url.
I use JQuery and the code is
$.get({
url: "http://address!!!!",
type: "GET",
success: function(result) {
console.log("yay");
console.log(result);
},
error: function (err) {
console.log(err);
},
});
If the above client code does not work, then try to add 'dataType: "json"'
你仍然以循环结束,所以这只会节省内存。
答案 1 :(得分:2)
这只是伪代码,因此无法保证完整性和正确性。
r = 0
for(int i=0; i<bits; i++) {
condition = (a >> i) & 1;
lookup = (b >> i) & 1;
if(condition == 1) {
r = (r << 1) | lookup;
}
}
鉴于这些意见......
a = 00101
b = 10100
bits = 5
算法表现如下。初始化结果。
r = 0
取最后一位,即i=0
。为了做到这一点,请转移到位置i
并使用和这样的操作踢出其余的数字:& 1
。为a
和b
执行此操作。然后检查过滤条件是否为真,在这种情况下,它意味着a
在最后一位有1
时。
i = 0
condition = (00101 >> 0) & 1 = 00101 & 1 = 00001 = 1
lookup = (10100 >> 0) & 1 = 10100 & 1 = 00000 = 0
r = (0 << 1) | 0 = 0 | 0 = 0
i = 1
condition = (00101 >> 1) & 1 = 00010 & 1 = 00000 = 0
lookup = (10100 >> 1) & 1 = 01010 & 1 = 00000 = 0
r = 0 // no modification here
i = 2
condition = (00101 >> 2) & 1 = 00001 & 1 = 00001 = 1
lookup = (10100 >> 2) & 1 = 00101 & 1 = 00001 = 1
r = (1 << 1) | 1 = 2 | 1 = 3
可以使用两个函数清理代码,例如:
lastAt(i, x) := (x >> i) & 1;
concatTo(r, v) := (r << 1) | v;
r = 0
for(int i=0; i<bits; i++) {
if(lastAt(i, a) == 1) {
r = concatTo(r, lastAt(i, b));
}
}
答案 2 :(得分:1)
这些操作不太可能成为您计划的瓶颈。所以我的建议只是使用一系列布尔值 - 不要为了逐位操作而烦恼,它会让你的程序更难理解和修改。
如果您真的担心花在这些操作上的执行时间,请在尝试优化之前进行一些仔细的基准测试或分析。我的猜测是,通过修改代码,将显示没有任何好处。
答案 3 :(得分:-2)
你的描述含糊不清,但从默默无闻中可以看出,这根本不是一个按位操作。在这种情况下,我提供真值表的原始建议是有效的,事实上你应该如何实现它:使用表查找。