Last active
December 11, 2015 20:59
-
-
Save yorkie/4659563 to your computer and use it in GitHub Desktop.
运用位级运算实现如下函数:even_ones[具体功能见注释]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 来自 @颜闽辉 | |
int bitmap(unsigned in, char out[]) | |
{ | |
unsigned count = 0; | |
unsigned size = sizeof(in) * 8; | |
out[size] = '\0'; | |
do { | |
if (in & 1) { | |
++count; | |
out[--size] = '1'; | |
} else { | |
out[--size] = '0'; | |
} | |
} | |
while (in >> 1, size); | |
return count; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 函数要实现的功能是: | |
// input: unsigned int | |
// output: 判断输入位模式中的置1位的奇偶性如: | |
// - 1(001) => 0(false, odd, 奇数个) | |
// - 3(011) => 1(true, even, 偶数个) | |
// - 8(1000) => 0(false, odd, 奇数个) | |
#include <stdio.h> | |
int main(int argc, char const *argv[]) | |
{ | |
unsigned x; | |
printf("Please input a positive number:\n"); | |
scanf("%u", &x); | |
if (x == 0u) | |
{ | |
printf("the number %d hava no '1' bit", x); | |
return 0; | |
} | |
printf("%s\n", even_ones(x) == 1 ? ":even" : ":odd"); | |
return 0; | |
} | |
// Return 1 when x contains an even number of 1s, 0 otherwise | |
unsigned is_even = 0u; | |
int even_ones(unsigned x) | |
{ | |
unsigned a = x; | |
if (a <= 0u) return (int)!is_even; | |
if (x & 1u == 1u) | |
is_even = !is_even; | |
return even_ones(a >> 1); | |
} | |
// 你有其他的实现吗? | |
// 欢迎提交与讨论,指正等 - ^.^ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 来自微博 @enginespot 的算法 | |
// 二进制步长为1,逢1变为0,逢0变1,问题直接变成数学问题,n%3==0,为偶数个,n%3>0 ,为奇数个 | |
int even_ones_v1(unsigned x) | |
{ | |
int temp = x % 3u; | |
if (temp == 0u) return 1; | |
else if (temp > 0u || 1u) return 0; | |
} | |
// 表达式版本 | |
int even_ones_v2(unsigned x) | |
{ | |
return !(x % 3u) ? 1 : 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
关于两种方法的对比:
从代码上看,循环不变式都是通过
x>>1
来实现的,唯一不同的是,我的前一个答案中是通过比较x & 1u
来标示,而下面的例子则是使用:这不得不引起关于位运算
^
的思考,首先我们来看看异或的真值表:再来看看
x & 1u
的真值表:第二种方法通过
& 1u
来获取其最高有效位的值,其并不关心个位以外的位,只要输入的数的当前最高有效位是1,就会通过^
让其改变当前值(即1>2,而2>1)。第一种方法中的
&
同样起着获取输入的数的最低有效位的作用。