- 题目1
一组数据中只有一个数字出现了一次。其他所有数字都是成对出现,请找出这个数字。
思路
寻找方法
如果输入的这几个数字有成对出现的情况,脑海里的闪过第一个寻找方法是通过乘除 的方法来筛选统计,通过相同数字乘以后除以他们的平方来找到最后这个数字。
但是这种方法微搓,而且麻烦,这时候就要考虑位运算操作符的性质了。
^
异或操作符
同一变量与另一变量和其异或值异或等于另一个数,如(a^b)^b=b
所以,
异或操作符
就可以用在交换两个数的内容而不借用第三变量。
a=a^b;
b=b^a;
a=a^b;
同样,两个相同的数相异或的结果便是零,一个数同零的异或就是他本身。根据这个性质,只需要将输入的所有数字全部异或,那么便会得到该数字。- 输入优化
定义一个整型数组,然后通过scanf将数字内容存储到数组内容中,不同于字符数组。整形数组一般的都用for循环来进行元素的逐个不同输入。
如果想在数组大小的范围内随意输入几个数字来进行检测,那么使用for循环就无法做到。
那么根据scanf的返回值即可尽可能的使输入灵活
scanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF。
- 输入优化
那么使用while循环,通过检测scanf的返回值,输入结束时只需输入非整型数或者出现EOF即可让scanf停止输入。
代码实现
int main()
{
int arr[15] = { 0 };
int i = 0;
int count = 0;
printf("请输入15个以内的数字,按CTRL+z结束");
while (EOF!=scanf("%d", &arr[i]))
{
count++; //记录用户输入数字的个数
i++;
}
i = 0;
int final = 0;
while (count)
{
final = final^arr[i]; //任何数与0相与或都为他本身
i++;
count--;
}
if (0 == final)
{
printf("成对出现");
}
else
{
printf("不成对");
}
system("pause");
return 0;
}
- 题目2
编写函数:
unsigned int reverse_bit(unsigned int value);
这个函数的返回 值value的二进制位模式从左到右翻转后的值。
思路
将该数字的二进制位每一位按位与&
,然后尽可能灵活的将位移动
代码实现
int bin_exc(unsigned int n)
{
int i = 31;
unsigned int goal = 0;
int sgl = n;//用于将第一个位移动到最左边
while (n!=0)
{
goal=(goal) | (sgl<< i); //point:先挪过去 因为第一次移动31位,相当于移动了单个位,因为前面的位没了
n = n >> 1;//再移位 警惕,区分移位和关系复合操作符的区别!
sgl = n & 1;//在这里将sgl的值更新
i--;
}
return goal;
}
int main()
{
int num = 0;
scanf("%d", &num);
printf("%u", bin_exc(num));//注意要以无符号的整型格式打印出,否则将进行负数补码计算
system("pause");
return 0;
}