首都之窗门户网站首页,成都市住房和城乡建设局电话,长春站最新发布,销售管理软件有哪些目录 一道变态的面试题#xff1a;不能创建临时变量#xff08;第三个变量#xff09;#xff0c;实现两个数的交换。
编写代码实现#xff1a;求一个整数存储在内存中的二进制中1的个数。 二进制位置0或者置1 如果以下的知识点不是很清楚的可以去看这篇文章#xff1…目录 一道变态的面试题不能创建临时变量第三个变量实现两个数的交换。
编写代码实现求一个整数存储在内存中的二进制中1的个数。 二进制位置0或者置1 如果以下的知识点不是很清楚的可以去看这篇文章操作符详解上-CSDN博客
一道变态的面试题不能创建临时变量第三个变量实现两个数的交换。
这个题如果没有那个限制条件我们一般都是创建第三个变量来处理。
法一
//创建临时变量
#include stdio.h
int main()
{int a 0;int b 0;printf(请输入交换前的变量a与b:);scanf(%d%d, a, b);int c 0;c a;a b;b c;printf(交换后a%d,b%d\n, a, b);return 0;
} 第二种方法可能也是比较容易想到的通过计算和来减去对应的。
法二 //加减法
#include stdio.h
int main()
{int a 0;int b 0;printf(请输入交换前的变量a与b:);scanf(%d%d, a, b);a a b;b a - b;//ab-ba a - b;//ab-aprintf(交换后a%d,b%d\n, a, b);return 0;
} 这个法二其实严格来说是有错误的。当a和b的值接近一个整形能存储的最大值是它们两的和就会超出这个整形的最大值从而导致溢出的问题。
第三种方法应该只有那些大佬才能够想到。 法三
#include stdio.h
int main()
{int a 0;int b 0;printf(请输入交换前的变量a与b:);scanf(%d%d, a, b);a a ^ b;b a ^ b;//a^b^baa a ^ b;//a^b^abprintf(交换后a%d,b%d\n, a, b);return 0;
} 这个方法涉及了一个知识点0^aaa^a0。
这个也用画图来解释一下吧 编写代码实现求一个整数存储在内存中的二进制中1的个数。
如果拿到这个题目的时候没思路的话就可以先想一想十进制求一个十进制数中1的个数那么这个也就比较简单了我们可以先%10看看最后一位是否等于1再/10赋给这个数更新一下再%10拿到倒数第二位看看是否等于1就这样一直%10/10知道最后这个/10的商为0就可以停止了。同理这个二进制我们也可以通过%2/2的方法来计算。
#include stdio.h
int main()
{int n 0;scanf(%d, n);int count 0;while (n){if (n % 2 1){count;}n / 2;}printf(%d\n, count);return 0;
}
但是很遗憾的是这个代码只能求正整数而对于负整数就不行了。
例如当我们输入-1时输出的却是0。我们知道-1的补码全是1正确输出的话应该要是32。
代码演示
其实这个问题还是比较好解决的既然负数不行那我们就把它变成无符号数而-1的补码是32个1那么对应的无符号数就是一个非常大的数字了。
#include stdio.h
int main()
{unsigned int n 0;scanf(%d, n);int count 0;while (n){if (n % 2 1){count;}n / 2;}printf(%d\n, count);return 0;
} 但是如果题目要求我们用的是有符号整数那么我们应该怎么办呢 其实这里就可以用到那个按位与操作符。这里我们就按照那个思路来想一想当给出了一个二进制数字我们按位与上一个1那么我们就只要看第32个比特位了因为两个数按位与的规则是对应的二进制位同为1才是1否则为0。而1的二进制补码只有第32个比特位才是1其余的都是0那么无论什么数按位与1最终的结果是前面的第31个都是0了只有第32个比特位还不确定。如果那个数第32个比特位为1那么最终的结果就是1如果那个数第32个比特位是0那么最终的结果就是0了。这是第32位的计算结果如果要想知道前面的结果就只能通过移位符来来把前面的比特位移至最后一位再来比较。这里可能有小伙伴会有疑问为什么不移1呢把1一位移位的移去前面来比较。其实这个移1也不是不可以但是比起移那个数还是要难一些。我们移1之后就表示判断结果等于1了而是等不等于0如果等于0那么就没有1如果不等于0那么就有1。原因我就用图来表述了 以上就是全部的思路接下来就用代码演示
移输入数的位
#include stdio.h
int main()
{int n 0;scanf(%d, n);int count 0;int i 0;for (i 1; i 32; i){if (n 1 1){count;}n 1;//注意这里千万不能是移i位因为i的数字是不断增加的而不是定值。}printf(%d\n, count);return 0;
}
#include stdio.h
int main()
{int n 0;scanf(%d, n);int count 0;int i 0;for (i 0; i 32; i){if ((n i) 1 1){count;}}printf(%d\n, count);return 0;
} 上面这两种写法都是可以的。
移 1 的位
#include stdio.h
int main()
{int n 0;scanf(%d, n);int count 0;int i 0;for (i 0; i 32; i){if ((n (1 i)) ! 0){count;}}printf(%d\n, count);return 0;
}
上面这个题目其实还能优化属于大佬能想到的
我就先把代码演示一下
#include stdio.h
int main()
{int n 0;scanf(%d, n);int count 0;while (n){n n (n - 1);count;}printf(%d\n, count);return 0;
}
这个代码最难理解的就是那个 n n (n-1)。这个表达式可以把从右往左把最左边的1给去掉。
画图演示
这个代码其实算法的体现是比较明显了 一般不容易想到。 二进制位置0或者置1 编写代码将n的二进制序列的第5位从右往左的第5位假设第5位是0修改为1然后再改回0。
这个题目应该是相较前面的难度要少一点。其实我们只要在第5位异或^一个1就可以了。利用异或的规则相异为1。至于这个第5位的1是怎么来实现呢我们只需要讲1向移4位就够了。第二部就在第5位按位异或^上一个1就可以了。因为我们前面改了第5位的数变成了1异或相同为0。
代码实现
#include stdio.h
int main()
{int n 0;scanf(%d, n);n ^ (1 4);printf(%d\n, n);n ^ (1 4);printf(%d\n, n);return 0;
}
代码演示 我们上面就举了个最简单的例子0任何一位都没有1第5位改了之后就变成了2的4次方等于16第二次我们又改回来了变成了0。