banner
李大仁博客

李大仁博客

天地虽大,但有一念向善,心存良知,虽凡夫俗子,皆可为圣贤。

使用遞歸位運算實現對字節的中心轉置反轉

字節的中心轉置反轉,這是一道的 IBM 技術面試題,供參考
原題如下:
給定一個任意字節長度的數據(以一個 Byte 為例),要求實現數據的位中心翻轉,
也就是數據的對稱位數據交換,比如:
1010 1100 -> 0011 0101
1111 1111 -> 1111 1111
0000 0000 -> 0000 0000
1111 0000 -> 0000 1111
解題思路也很簡單,只要使用位運算實現以下的位變化即可,但是需要考慮到其他
位的情況,注意運算符的使用即可,IBM 不愧是 IBM
11 - > 11
00 - > 00
10 - > 01
01 - > 10

以下是 C 語言和 VB.net 語言的兩種解題實現的代碼,VB 涉及位轉換,效率較低
,但是算法是一樣的,同時,這裡使用了遞迴算法

VB.net

'全局變量,保存需要轉換的數據
Private val As Byte

''' ''' 核心算法,使用遞迴實現一個Byte的字節中心轉置
''' 
''' 
''' 
Private Sub fun(ByVal a As Byte)
    If a = 0 Then
        Exit Sub
    End If
    '11 - > 11
    '00 - > 00
    '10 - > 01
    '01 - > 10
    '算法在於排除11和00的情況,01和10反轉
    '排除and之後全是0的情況
    If (val And a) <> (CByte(128 / a) And val) Then
        '其中一個為0,另一個必為1 , 全1的情況自然排除
        If (val And a) = 0 Or (CByte(128 / a) And val) = 0 Then
            '進行位運算
            val = CByte(val Xor (a + CByte(128 / a)))
        End If
    End If
    '遞迴調用
    fun(a / 2)
End Sub

C/C++

//C 語言實現一個 Byte 的字節中心轉置
#include #include #define BYTE 8
//#define INTEGER 16

#define LENGTH BYTE
//#define LENGTH INTEGER

// 求出算子,用於參數傳遞
#define ARGUMENT pow(2 , (LENGTH / 2 - 1))
//#define ARGUMENT 1 << ( LENGTH/2 -1 )

#define HIGHT 0x80 /*1000 0000*/
//#define HIGHT 0x8000 /*1000 0000 0000 0000*/

unsigned short val = 0;
//unsigned int val = 0;

int fun(int a){
//a 為空,返回
if (0 == a) {
return 0;
}
//'11 - > 11
//'00 - > 00
//'10 - > 01
//'01 - > 10
//' 算法在於排除 11 和 00 的情況,01 和 10 反轉
//' 排除 and 之後全是 0 的情況
if ( (val & a) != ((HIGHT / a) & val) ){
// 其中一個為 0,另一個必為 1 , 全 1 的情況自然排除
if ( 0 == (val & a) || 0 == ((HIGHT / a) & val) ) {
// 進行位運算
val = val ^ ((HIGHT / a) + a);
}
}
fun(a / 2);
//func(a >> 1);
return 1;
}

int main(int argc , char * args[]) {
// 輸入
scanf("%d", &val);
// 遞迴調用
fun(ARGUMENT);
// 輸出
printf("%d", val);
return 0;
}

完整代碼下載
http://www.lidaren.com/code/bytecvt/src.zip
VB 運行效果

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。