[题记]位运算和scanf的简单应用

  • 题目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;
}
![III](https://img-blog.csdn.net/20180419130733392?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxNjM1MDc1ODAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

  • 题目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;
}

猜你喜欢

转载自blog.csdn.net/qq635075803/article/details/80003431
今日推荐