第一章:位运算-------出现k次与出现1次
问题:
数组中只有一个数出现了一次,其他的数都出现了k次,请输出只出现1次的数。
知识点:
2个相同的2进制数,做不进位加法,结果为0;
10个相同的10进制数,做不进位加法,结果为0;
k个相同的k进制数,做不进位加法,结果为0;
思路:
将这些数,全部转换为k进制数,然后做不进位加,最后将结果转换为十进制数。
#include<iostream>
#include<algorithm>
//#include<cmath>
using namespace std;
//十进制数转K进制
string decTok(int dec,int k){
string ret=""; //作为结果
while(dec>0){
ret+=char(dec%k+'0'); //如:5+'0'='5'
dec/=k;
}
reverse(ret.begin(),ret.end());
return ret;
}
//K进制转十进制
int kTodec(string str,int k){
int ans=0;
for(int i=0;i<str.size();i++){
ans=ans*k+(str[i]-'0'); //020 首位是最高位
//ans+=(str[i]-'0')*pow(k,str.size()-1-i);
}
return ans;
}
int main(){
int n[]={1,1,1,3,3,3,5,5,5,9,9,9,6,7,7,7};
int k=3;
string str[16];
for(int i=0;i<16;i++){
str[i]=decTok(n[i],k);
}
//找出16条字符串中最大长度
int maxlen=0;
int len;
for(int i=0;i<16;i++){
len=str[i].size();
maxlen=max(maxlen,len); //不能用: maxlen=max(maxlen,str[i].size())
}
//16条字符串中,若字符串长度<maxlen,则进行补齐,以便逐位做不进位加
for(int i=0;i<16;i++){
while(str[i].size()<maxlen){
str[i]="0"+str[i];
}
}
//ans:结果。初始化
string ans="";
while(ans.size()<maxlen){
ans+="0";
}
//16条字符串做不进位加
for(int i=0;i<16;i++){
for(int j=0;j<maxlen;j++){
ans[j]=char(((str[i][j]-'0')+(ans[j]-'0'))%k+'0');
}
}
cout<<ans<<endl;
//ans字符串结果转为10进制数
int finalans=kTodec(ans,k);
cout<<finalans<<endl;
return 0;
}