1.位运算:
道理就不解释了直接看代码,具体源代码和题目直接留言就好了
具体代码和截图在下面
题目一:
找出一个数字里面一的个数,比如3(11)输出2
代码:
利用位运算
法一(每次往右边移动,每次移动一次就加上去)
#include <iostream>
using namespace std;
int main()
{
int n,count=0;
cin>>n;
while(n)
{
if(n&1==1) count++;//如果当前位置是1就加上去
n>>=1;//把当前数字拿去移动,每次移动一格
}
cout<<count<<endl;
return 0;
}
法二:将0000000000…1移动32次,32正好是一个int表示的大小
枚举32位所有可能,每次枚举的时候,除了该位是1其他位置都是0,所以每次判断是否&后和生成的这个数一样
#include <iostream>
using namespace std;
int main()
{
int n,count=0;
cin>>n;
for(int i=0;i<32;++i)
{
if(((1<<i)&n)==(1<<i))
{
count++;
}
}
cout<<count<<endl;
return 0;
}
法三:我们思考这样的一个东西,我们模拟数1,每次数到一个1就记录消除这个1,那么我们消除几次这个1就代表我们有几个1;
这样想的话很简单;我们每次把这个数n和(n-1)进行&运算就好了
比如5是101
101 (-)1是 100 &101后就是100
100(-)1是 011 &100后就是000
结束 操作了2次就2个
代码:
#include <iostream>
using namespace std;
int main()
{
int n,count=0;
cin>>n;
while(n)
{
n=n&(n-1);
count++;
}
cout<<count<<endl;
return 0;
}
题目:设计一个算法,计算出n阶乘中尾部零的个数
思路:尾部的0要如何计算呢,尾巴的0是如何出来的呢,就是因为10出来的,10就是2*5的乘积;5的个数就是次数;
代码:
public static long trailingZeros(long n) {
int count=0;
while(n!=0)//如果n还有的话,就继续除
{
n/=5;//计算当前5的个数还有多少个
count+=n;//加进去这个数
}
return count;
}
题目:写一个程序来检测一个整数是不是丑数。
丑数的定义是,只包含质因子 2, 3, 5 的正整数。比如 6, 8 就是丑数,但是 14 不是丑数因为他包含了质因子 7。
代码:
public class Solution {
/**
* @param num: An integer
* @return: true if num is an ugly number or false
*/
public boolean isUgly(int num) {
if(num<=0) return false;
while(num!=1)
{
if(num%2==0)//如果num对2,3,5除得尽就除掉,如果除不掉就return false
{
num/=2;
}
else if(num%3==0)
{
num/=3;
}
else if(num%5==0)
{
num/=5;
}
else return false;
}
return true;
}
}
题目:
判断一个数字是不是2的次方:
代码:
#include <iostream>
#include <algorithm>
using namespace std;
int a[10010];
int main()
{
int n,i=0;
cin>>n;
while(n)
{
if(n&1==1) i++;
n>>=1;
}
if(i==1) cout<<"yes";
else cout<<"no";
return 0;
}
#include <iostream>
#include <algorithm>
using namespace std;
int a[10010];
int main()
{
int n,i=0;
cin>>n;
if(n&(n-1)==0) cout<<"yes"<<endl;//第一次&一下就是0的话,证明只有一个1
else cout<<"no"<<endl;
return 0;
}
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int a[10010];
int main()
{
double a;
int sum=0;
string s;
cin>>a;
s+="0.";
while(a>0)
{
double aa=a*2;
if(aa>=1.0)
{
s+="1";
a=aa-1.0;
}
else if(aa<1)
{
a=aa;
s+="0";
}
sum++;
if(sum>32)
{
cout<<"not"<<endl;
return 0;
}
}
cout<<s<<endl;
return 0;
}
这里补充一个重点的二进制;
二进制如何表示浮点数;
比如表示0.625;
乘2消整法:
0.6252=1.25
消除整数位1
输出1;
变成0.25
0.252=0.5;
输出0
0.5*2=1;
输出1;
消1
变为0
所以就是0.101;
代码:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int a[10010];
int main()
{
double a;
int sum=0;
string s;
cin>>a;
s+="0.";
while(a>0)
{
double aa=a*2;
if(aa>=1.0)
{
s+="1";
a=aa-1.0;
}
else if(aa<1)
{
a=aa;
s+="0";
}
sum++;
if(sum>32)
{
cout<<"not"<<endl;
return 0;
}
}
cout<<s<<endl;
return 0;
}