有许多方法可以迭代n-bit Gray codes。有些比其他更有效。但是,我实际上并不需要格雷码,而是希望迭代格雷码列表中更改的位索引,而不是实际的格雷码。例如,取这个3位格雷码列表:
000,001,011,010,110,111,101,100
我想输出3,2,3,1,3,2,3。这告诉我们需要更改位3,2,3等才能获得列表。在这里,我从1和左边开始索引。
执行此操作的一种方法是按顺序计算格雷码,并为每个连续对(x,y)计算(x XOR y)以识别哪个位发生了变化,然后取整数对数基数2(x XOR) Y)。
然而,我需要尽可能快地进行迭代,我的兴趣将是30-40位格雷码。
有一种有效的方法吗?
答案 0 :(得分:3)
如果将从0开始的位编号为最小有效位,则要更改以增加二进制反射格雷码的位的位置是以增加的二进制数设置的最低位的位置(请参阅维基百科段落的结尾处)你联系了) - 为了获得你所呈现的编号,从3 /位位数减去。
binary-reflected ("Gray") 000 001 011 010 110 111 101 100
binary 001 010 011 100 101 110 111
pos of least significant 1 0 1 0 2 0 1 0
(count of trailing zeros ctz)
3 - ctz(binary) 3 2 3 1 3 2 3
答案 1 :(得分:1)
如果您正在使用,例如,C与GCC内在函数(并且你肯定应该使用一种语言,让你可以很好地控制程序集输出,以便你可以进行矢量化),那么你可以做
long long ctr = 0LL;
int next() { return __builtin_ctzll(++ctr); }
通过计算计数器ctr
的尾随零来返回0,1,0,2,0,1,0,3,0,1 ......。
酌情翻译。