C语言——小知识和小细节19

一、奇数位与偶数位互换

1、题目介绍

实现一个宏,将一个整数的二进制补码的奇数位与偶数位互换。输出格式依旧是十进制整数。示例:

2、分析

既然想要交换奇数位和偶数位上的数字,那么我们就要先得到奇数位和偶数位上的数字,那么如何得到呢。我们可以使用以下方法(以下的二进制都是补码):

将目的转换数字按位与上一个偶数位全是1奇数位全是0的特殊数字,就可以得到一个数字,这个数字奇数位上都为0,偶数位上的数字与目的转换数字的偶数位上一样,这里的特殊数字为01010101 01010101 01010101 01010101 转换为十进制为1431655765,这里可以直接使用十六进制0x55555555。同理,得到奇数位使用下面的方法,但是这个特殊的数字就是一个负数了:

这里的特殊数字为10101010 10101010 10101010 10101010 由于这里是补码,符号位为1,为负数,转换为原码为11010101 01010101 01010101 01010110 ,转换为十进制为-1431655766。我们这里可以直接使用十六进制,十六进制的话就不用从补码转换为原码了,可以直接使用补码转换为十六进制0xaaaaaaaa。

这样我们就得到了目的转换数字的奇数位和偶数位上的数字了,然后我们就要将奇数位和偶数位调整一下位置,将奇数位移到偶数位置,也就是右移一位,将偶数位移到奇数位置,也就是左移一位:

然后将调整位置后的两个奇数位和偶数位的数字按位或,就可以得到结果,结果为00000000000000000001011011101 ,转换为十进制就是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;
}

运行结果:

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值