Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 不使用循环按位反转整数_Algorithm - Fatal编程技术网

Algorithm 不使用循环按位反转整数

Algorithm 不使用循环按位反转整数,algorithm,Algorithm,我想写一个反整数位的程序。 Ex 11000101至10100011 我知道如何使用循环解决这个问题,但我遇到了使用字节移位的解决方案: num>>4|num<<4 num>>4 | num这不是反转位,而是交换nybles(4位单位)。换言之,它将转向: 1100 0101 (abcd efgh) 进入: 只有当数据类型实际上是8位(否则num>2)|((num&0x33)>1)|((num&0x55)1100 0101时,它才会这样做 >4表示我们正在将位右移4位

我想写一个反整数位的程序。
Ex 11000101至10100011
我知道如何使用循环解决这个问题,但我遇到了使用字节移位的解决方案:

num>>4|num<<4

num>>4 | num这不是反转位,而是交换nybles(4位单位)。换言之,它将转向:

1100 0101 (abcd efgh)
进入:

只有当数据类型实际上是8位(否则
num>2)|((num&0x33)>1)|((num&0x55)1100 0101时,它才会这样做

>4
表示我们正在将位右移4位:

0000 1100


如前所述,它不是反转位,只是反转半字节。但您也可以将真正的位反转分解为类似的内容,例如(未测试):

//交换半字节

x=x>>4 | x>2)&0x33 |(x&0x33)>1)&0x55 |(x&0x55)如果您的整数在范围
0..255
内,可以将所有
256
反向值制成表格。(你可以把一小口列成表格,但这是穷人的解决办法。)


对于较大的值,使用该表交换并同时反转字节。您可以通过掩码和移位的组合,或者通过将四个字节映射到int来进行交换。

一种用于反转整数中位顺序的递归方法——使用要反转的值和值的宽度调用

procedure int REVERSEBITS( int VALUE; int WIDTH ) {
  if WIDTH==1 then {
    return VALUE;
  } else {

    // intermediate values may help make the algorithm more understandable
    int HalfWidth = WIDTH >> 1;  // number of bits to be swapped at this level
    int HalfMask = HalfWidth-1;  // mask for left or right half of the value
    int RightHalfValue = VALUE & HalfMask;  // extract right half from value
    int LeftHalfValue = (VALUE >> HalfWidth) & HalfMask;  // extract left half

    // call reversing function on the two halves separately then swap the results
    return (REVERSEBITS(RightHalfValue, HalfWidth) << HalfWidth)
                | REVERSEBITS(LeftHalfValue, HalfWidth);
  }
}
过程int反转息税前利润(int值;int宽度){
如果宽度==1,则{
返回值;
}否则{
//中间值可能有助于使算法更易于理解
int HalfWidth=WIDTH>>1;//在此级别要交换的位数
int HalfMask=HalfWidth-1;//值的左半部分或右半部分的掩码
int rightshalfvalue=VALUE&HalfMask;//从值中提取右半部分
int LeftHalfValue=(值>>HalfWidth)&HalfMask;//提取左半部分
//分别调用两半上的反转函数,然后交换结果
收益(反向息税前利润(右半值,半宽度)>1)-1),(宽度>>1))>1))
|反向息税前利润(((值>>(宽度>>1))和((宽度>>1)-1)),(宽度>>1));
}
}
通过更改函数定义,稍微简化函数代码,即使用要反转的值和值的一半宽度进行调用

procedure int REVERSEBITS( int VALUE; int WIDTH ) {
  if WIDTH==0 then {
    return VALUE;
  } else {
    return (REVERSEBITS((VALUE & (WIDTH-1)), (WIDTH >> 1)) << WIDTH)
        | REVERSEBITS(((VALUE >> WIDTH) & (WIDTH-1)), (WIDTH >> 1));
  }
}
过程int反转息税前利润(int值;int宽度){
如果宽度==0,则{
返回值;
}否则{
收益(反向息税前利润((值和(宽度-1)),(宽度>>1))>宽度)和(宽度-1)),(宽度>>1));
}
}

您不了解哪一部分?在这里您可以找到人类已知的所有位反转方法:
  ((num & 0x01) << 7)
| ((num & 0x02) << 5)
| ((num & 0x04) << 3)
| ((num & 0x08) << 1)
| ((num & 0x10) >> 1)
| ((num & 0x20) >> 3)
| ((num & 0x40) >> 5)
| ((num & 0x80) >> 7)
num = ((num & 0xf0) >> 4) | ((num & 0x0f) << 4) // abcdefgh -> efghabcd
num = ((num & 0xcc) >> 2) | ((num & 0x33) << 2) // efghabcd -> ghefcdab
num = ((num & 0xaa) >> 1) | ((num & 0x55) << 1) // ghefcdab -> hgfedcba
0xf0, 0x0f -> 1111-0000, 0000-1111, shift by 4
0xcc, 0x33 -> 1100-1100, 0011-0011, shift by 2
0xaa, 0x55 -> 1010-1010, 0101-0101, shift by 1
(num&0xcc)>>2     (num&0x33)<<2
-------------     -------------
  abcdefgh          abcdefgh
  11001100          00110011        'and' with mask
  --------          --------
  ab00ef00          00cd00gh
  00ab00ef          cd00gh00        shift right/left
          \        /
           00ab00ef
           cd00gh00                 'or' them together
           --------
           cdabghef
ab   cd   ef   gh
  \ /       \ /
   X         X
  / \       / \
cd   ab   gh   ef
0000 1100 
↓↓↓↓ ↓↓↓↓ |
0101 0000
---------
0101 1100
// swap nibbles
x = x >> 4 | x << 4;
// swap groups of 2
x = (x >> 2) & 0x33 | (x & 0x33) << 2;
// swap groups of 1
x = (x >> 1) & 0x55 | (x & 0x55) << 1;
procedure int REVERSEBITS( int VALUE; int WIDTH ) {
  if WIDTH==1 then {
    return VALUE;
  } else {

    // intermediate values may help make the algorithm more understandable
    int HalfWidth = WIDTH >> 1;  // number of bits to be swapped at this level
    int HalfMask = HalfWidth-1;  // mask for left or right half of the value
    int RightHalfValue = VALUE & HalfMask;  // extract right half from value
    int LeftHalfValue = (VALUE >> HalfWidth) & HalfMask;  // extract left half

    // call reversing function on the two halves separately then swap the results
    return (REVERSEBITS(RightHalfValue, HalfWidth) << HalfWidth)
                | REVERSEBITS(LeftHalfValue, HalfWidth);
  }
}
procedure int REVERSEBITS( int VALUE; int WIDTH ) {
  if WIDTH==1 then {
    return VALUE;
  } else {
    return (REVERSEBITS((VALUE & ((WIDTH>>1)-1)), (WIDTH>>1)) << (WIDTH>>1))
        | REVERSEBITS(((VALUE >> (WIDTH>>1)) & ((WIDTH>>1)-1)), (WIDTH>>1));
  }
}
procedure int REVERSEBITS( int VALUE; int WIDTH ) {
  if WIDTH==0 then {
    return VALUE;
  } else {
    return (REVERSEBITS((VALUE & (WIDTH-1)), (WIDTH >> 1)) << WIDTH)
        | REVERSEBITS(((VALUE >> WIDTH) & (WIDTH-1)), (WIDTH >> 1));
  }
}