一、奇数位与偶数位互换
1、题目介绍
实现一个宏,将一个整数的二进制补码的奇数位与偶数位互换。输出格式依旧是十进制整数。示例:
2、分析
既然想要交换奇数位和偶数位上的数字,那么我们就要先得到奇数位和偶数位上的数字,那么如何得到呢。我们可以使用以下方法(以下的二进制都是补码):
将目的转换数字按位与上一个偶数位全是1奇数位全是0的特殊数字,就可以得到一个数字,这个数字奇数位上都为0,偶数位上的数字与目的转换数字的偶数位上一样,这里的特殊数字为01010101 01010101 01010101 01010101 转换为十进制为1431655765,这里可以直接使用十六进制0x55555555。同理,得到奇数位使用下面的方法,但是这个特殊的数字就是一个负数了:
这里的特殊数字为10101010 10101010 10101010 10101010 由于这里是补码,符号位为1,为负数,转换为原码为11010101 01010101 01010101 01010110 ,转换为十进制为-1431655766。我们这里可以直接使用十六进制,十六进制的话就不用从补码转换为原码了,可以直接使用补码转换为十六进制0xaaaaaaaa。
这样我们就得到了目的转换数字的奇数位和偶数位上的数字了,然后我们就要将奇数位和偶数位调整一下位置,将奇数位移到偶数位置,也就是右移一位,将偶数位移到奇数位置,也就是左移一位:
然后将调整位置后的两个奇数位和偶数位的数字按位或,就可以得到结果,结果为00000000 00000000 00000101 11011101 ,转换为十进制就是1501,与上面的示例结果相同。
3、代码
以下为具体代码实现:
#include <stdio.h>
// 定义宏来交换奇数位和偶数位
#define SWAP_ODD_EVEN_BITS(n) (((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1))
int main() {
int num = 2798;
int result = SWAP_ODD_EVEN_BITS(num);
printf("Original number: %d\n", num);
printf("Number after swapping odd and even bits: %d\n", result);
return 0;
}
运行结果:
二、将空格替换为%20
将一个字符串中的空格全部替换成%20。
1、方法一
只要读取到一个空格则将空格后面的字符串向后移两位,然后从空格这里加入%20。
代码:
#include <stdio.h>
#include <assert.h>
#include <string.h>
void Convert(char* str) {
assert(str);
char* string = str;
while (*string) {
if (*string == ' ') {
int len = (int)strlen(string);
char* temp = string + len + 2;
while(len) {
*temp = *(temp - 2);
temp--;
len--;
}
*string = '%';
*(string + 1) = '2';
*(string + 2) = '0';
string += 2;
}
string++;
}
}
int main() {
char str[120] = "i love you. olive juice";
Convert(str);
printf("%s\n", str);
return 0;
}
运行结果:
2、方法二
首先统计空格的个数,然后使用两个下标,因为一个空格扩充到%20就多出两个字符,所以第一个下标在字符长度加上二乘上空格的个数处,第二个下标在字符串的 \0 字符处,然后从后向前遍历字符串,当前面的下标遇到空格,则后面的下标开始填充%20,直到两个下标相遇。
代码:
#include <stdio.h>
#include <assert.h>
#include <string.h>
void Convert(char* str) {
assert(str);
char* string = str;
int space_num = 0;
while (*string) {
if (*string == ' ') {
space_num++;
}
string++;
}
int left = (int)strlen(str);
int right = (int)strlen(str) + space_num * 2;
while (left != right) {
if (str[left] == ' ') {
str[right] = '0';
str[right - 1] = '2';
str[right - 2] = '%';
right -= 2;
}
else {
str[right] = str[left];
}
left--;
right--;
}
}
int main() {
char str[120] = "i love you. olive juice";
Convert(str);
printf("%s\n", str);
return 0;
}
运行结果: