1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现。
分析:两个相同的数进行异或(^)运算得到0
//找出唯一成对的数
#include
#include
using namespace std;
int main(){
int N = 11;
int tmp=0;
int arr[N];
int index = rand()%(N-1);
for(int i=0;i<N;i++){
arr[i] = i+1;
}
arr[N-1] = index+1;
cout<<"打印数组:" ;
for(int i=0;i<N;i++)
cout<<arr[i]<<" ";
cout<<endl;
for(int i=0;i<N;i++){
tmp=tmp^(i);
}
for(int i=0;i<N;i++){
tmp=tmp^arr[i];
}
cout<<"重复的数字是"<<tmp<<endl;
return 0;
}
一个数组里除了某一个数字之外,其他的数字都出现了两次,请写程序找出这个只出现一次的数字
分析:同1
//找出落单的数
#include
using namespace std;
int main(){
int N = 10;
int arr[2*N+1];
cout<<"打印数组:" ;
for(int i=0;i<2*N+1;i++){
arr[i] = i/2;
cout<<arr[i]<<" ";
}
cout<<endl;
int tmp=0;
for(int i=0;i<2*N+1;i++){
tmp = tmp^arr[i];
}
cout<<"落单的数字是"<<tmp<<endl;
return 0;
}
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。
例: 9的二进制表示为1001,有2位是1
分析:与(&)运算,n&(n-1)可以消去一个数最低位上的1
//二进制数中1的个数
#include
using namespace std;
int numberOfOne(int n){
int number=0;
while(n){
n = n&(n-1);
number++;
}
return number;
}
int main(){
cout<<"9中有"<<numberOfOne(9)<<"个1"<<endl;
return 0;
}
用一条语句判断一个整数是不是2的整数次方
分析:同3
//判断一个整数是不是2的整数次方
#include
using namespace std;
int main(){
int n=8;
if (n>0&&n^(n-1))
cout<<"是2的整数次方";
else
cout<<"不是2的整数次方";
}
将一个数的二进制表示中的奇数位和偶数位互换
分析:使用&运算分别提取出奇数位和偶数位,然后用>>和<<移动一位后用|或^运算相加。
//将整数的奇偶位互换
#include
using namespace std;
int main(){
int ou = 0xaaaaaaaa;
int ji = 0x55555555;
int m =9;
int n1,n2;
n1 = m&ou;
n2 = m&ji;
n1 = n1>>1;
n2 = n2<<1;
cout<<(n1^n2)<<endl;
}
给定一个介于0和1之间的实数,(如0.625),类型为double,打印它的二进制表示(0.101,因为小数点后的二进制分别为0.5,0.25,0.125……)。
如果该数字无法精确用32位以内
分析:乘2,挪整
//0~1之间浮点实数的二进制表示
#include
#include
#include
using namespace std;
int main(){
double n = 0.3;
string str="0.";
bool flag = true;
while(n>0){
n*=2;
if(n>=1){
str.append("1");
n = n-1;
}
else
str.append("0");
if(str.size()>34){
cout<<"ERROR";
flag = false;
break;
}
}
if(flag)
cout<<str<<endl;
}
数组中只有一个数字出现了一次,其他的数都出现了k次,请输出只出现了1次的数
分析:先转为k进制,做不进位加法,
K个相同的K进制数进行无进位加法,相加的结果一定是每一位上都为0的K进制数
//出现k次与出现1次
#include
#include
#include
using namespace std;
string dectok(int n, int k){
string str = "";
while(n>0){
str += n%k+'0';
n /= k;
}
reverse(str.begin(),str.end());
return str;
}
int ktodec(string n,int k){
int dec = 0;
for(int i=0;i<n.size();i++){
dec += (n[i]-'0')*pow(k,n.size()-i-1);
}
return dec;
}
int main(){
int k = 3;
int arr[16]={2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0};
string str[sizeof(arr)/sizeof(arr[0])];
cout<<"打印数组:" ;
for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++){
cout<<arr[i]<<" ";
}
cout<<endl;
int maxlen=0,tmp;
//将十进制数转为k进制,并计算k进制字符的最大长度
for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++){
str[i]=dectok(arr[i],k);
tmp = str[i].size();
maxlen=max(tmp,maxlen);
}
//将所有字符都补成一样的长度,方便进行不进位加法
for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++){
while(str[i].size()<maxlen){
str[i]="0"+str[i];
}
}
string result="";
while(result.size()<maxlen){
result+="0";
}
for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++){
for(int j=0;j<maxlen;j++){
result[j]=char(((str[i][j]-'0')+(result[j]-'0'))%k+'0');
}
}
cout<<"出现1次的数为"<<ktodec(result,k)<<endl;
return 0;
}