已知1001大小的数组,分别为1-1000,其中只有两个数是相同的,找出这个数
解法1:使用位运算异或可以消除重复,11=0,22=0即自己异或自己等于0,那么用1-1000异或得到x,1001大小的数组异或得到y,再x^y即得到结果
//核心代码
int a[1001];
int x = 0, y = 0;
for(int i = 1; i <= 1000; i++)
x = x ^ i;
for(int j = 1; j < 1001; j++)
y = y ^ a[j];
printf("%d", x ^ y);
解法2:全部加出来再减去1-1000的和就得到了
解法3:用辅助空间1001大小的数组(0下标不用),遍历一遍要判断的数组,对应辅助空间内容++就可以,出现2就判断完成
int a[1001];
int temp[1001] = {0};//全部初始化为0
for(int i = 0; i < 1001; i++){
temp[a[i]]++;
if(temp[a[i]] == 2)
printf("%d", i);
}
找一个落单的数:一个数组里除了某一个数字之外,其他数字都出现了两次,找出只出现一次的数字。
用异或就可以了
int a[N];
int temp = 0;
for(int i = 0; i < N; i++)
temp = temp ^ a[i];
printf("%d", temp);
二进制中1的个数:输入一个整数,输出该数二进制数表示中1的个数
解法1:用1与,每次右移一位
int n;
scanf("%d", &n);
int sum = 0;
for(int i = 1; i <= 32; i++){//这里int是32位,也可以用8*sizeof(int)
if(n & 1)
sum++;
n = n >> 1;
}
printf("%d", sum);
解法二:用n-1和n与,每次与会消去从右往左数的第一个1,计数消去的次数就得到了1的个数,如1000b & 111b = 0
int main(int argc, char* argv[]){
int n = 1;
int sum = 0;
while(n){
sum++;
n = (n - 1) & n;
}
printf("%d", sum);
return 0;
}
是不是2的整数次方:用一条语句判断
2的整数次方的二进制只有一位是1,如10b,100b,1000b,用n-1和n与,若只有一个1,则结果为0
if(((n-1) & n) == 0)
将整数的奇偶位互换(交换的是二进制的)
分别去除奇数位(和0xaaaaaaaa与)、偶数位(和0x55555555与),再将去除了奇数位的左移一位,去除了偶数位的右移一位,然后进行或运算(异或运算也可以)
#include "stdafx.h"
int main(int argc, char* argv[]){
int x = 0x55555555;
int y = 0xaaaaaaaa;
int n, result;
scanf("%d", &n);
x = n & x;//保留奇数位
y = n & y;//保留偶数位
x = x << 1;
y = y >> 1;
result = x | y;
printf("%d", result);
return 0;
}
给定一个0-1间的数,用二进制表示
每次乘2,整数位为1就输出1并减1,为0输出0,直到变为0
#include "stdafx.h"
int main(int argc, char* argv[]){
double x;
scanf("%lf", &x);
printf("0.");
while(x){
x = 2 * x;
if(x >= 1){
printf("1");
x -= 1;
}
else
printf("0");
}
return 0;
}
数组中只有一个数出现了一次,其他的数出现了k次,输出只出现一次的数
可以用哈希表,二进制做法看不懂