关闭

程序员面试金典: 9.5位操作 5.6交换某整数的奇数位和偶数位

78人阅读 评论(0) 收藏 举报
分类:
#include <iostream>
#include <stdio.h>

using namespace std;

/*
问题:编写程序,交换某个整数的奇数位和偶数位,使用指令越少越好(也就是说,位0与位1交换,位2与位3交换,依此类推)
分析:比如1011: 0111,也就是向前移动,
      【注意最高位需要移动到最低位处,陷阱是:所看到的最高位可能不是正确的,需要分析
      如果该整数为正整数,那么没有问题,直接按照上述处理:
	  如果为负整数,比如 -8转换为-(0000 0000 0000 0000 0000 0000 0000 1000) =>
	                               1111 1111 1111 1111 1111 1111 1111 1000
								   那么其实负数的最高位是1 ,似乎是没有陷阱的 】
	  问题的本质是让我们减少指令次数,如果记录整数的最高位的值为h,最低位为l,将n向左移动1位,然后将n和h进行或运算,
	  总共指令 = 寻找整数n最高位h + n左移1次 +  n与h或运算
	  关键就是寻找最高位h,32位整数只需要将 n & (1 << 32) 的值记为h即可,所以总共只需要3次
	  注意要判定当前系统的整数位
输入:输入1个十进制整数,整数可能为负数
11
-8
输出:
7
-12

弄错:误解题目意思,题目意思不是左移,而是奇数位和偶数位分别交换。
      1001 -> 0110
	  所谓的交换 = 奇数位

关键:
1
书上解法:
牛逼,设整数为n,通过 n & 10101010 提取出奇数位的值为nOdd, 然后将nOdd向右移动1位
                     n & 01010101 提取出偶数位的值为nEven, 然后将nEven向左移动1位
					 将nOdd 与 nEven 进行或运算,
没想到单独提取奇数位和偶数位
所以共需要5次= 提取奇数位+提取偶数位+奇数位右移1位+偶数位左移一位+奇数位与偶数位对应的数进行或运算
2 10101010转换为十六进制为0xaaaaaaa
*/

int swapOddAndEvenBit(int n)
{
	int nOdd = n & (0xaaaaaaaa);
	int nEven = n & (0x55555555);
	nOdd >>= 1;
	nEven <<= 1;
	int result = nOdd | nEven;
	return result;
}

void process()
{
	int n;
	while(cin >> n)
	{
		n = swapOddAndEvenBit(n);
		cout << n << endl;
	}
}

int main(int argc, char* argv[])
{
	process();
	getchar();
	return 0;
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:430971次
    • 积分:12496
    • 等级:
    • 排名:第1119名
    • 原创:842篇
    • 转载:109篇
    • 译文:5篇
    • 评论:28条
    最新评论