#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;
/*
* 1.唯一成对的数
法一:异或 可理解为不进位加法 ,消除重复,可找含有唯一2个重复的数(1-1000与1-1001个数异或,唯一的数被消去,剩下重复的数留下)
(法一需知道范围数组才可用,否则法二)
法二:开辟空间1001,出现的数字在对应空间位置加一,help[a[i]]++;
*/
void QAQ1() {
int n = 1001;
int a[1001];
for (int i = 0; i < 1000; i++) {
a[i] = i + 1;
}
a[1000] = (rand()%10 + 1);//最后一个重复的数是随机数1-1001 , rand()产生一个0-0x7fff(0-32767)的随机数,即最大是32767
int x1 = 0;
for (int i = 1; i <= n - 1; i++) {
x1 = (x1 ^ i);//异或
}
for (int i = 1; i < n ; i++) {
x1 = x1 ^ a[i];//不用开辟空间
}
cout << x1 << endl;
//开辟空间
/*cout << ---------一条优美的分界线----------- << endl;
int help[1001];
for(int i = 0;i < n;i++){
help[a[i]]++;
}
for(int i = 0;i < n;i++){
if(help[i] == 2)
cout << i << endl;
}
*/
}
/*求二进制中1的个数
法一:1左移和N与运算相同则加一 ,判读二进制每一位上是不是1
法二:(x-1)&x 效果消掉低位的1变成0 【11000 - 1 = 10111 , 11000 & 10111 = 10000 】
/括:用一条语句判读整数是不是2的整数次方 if((N-1)&N == 0)
*/
void QAQ2() {
int N;
cin >> N;//输入od十进制转二进制ob ????????????
//-----------------转二进制
int count = 0;
//法一
for (int i = 0;i < 32;i++) { //32位
if ((N & (1 << i)) == (1 << i)) {//其他位位0,且的性质消掉,等效把1移动从1-32位依次比较 <<优先级大于==,加括号
count++;
}
}
/*
//法二
while (N != 0) {
N = ((N - 1) & N);
count++;
}
*/
cout << count << endl;
}
/*位运算
* 整数的奇偶位交换(和010101010101010101 。。。32位&运算后得到保留奇数位值,同理101010101010。。。32位得到偶数位值)
奇左移一位,偶右移一位,两个再异或得到奇偶位交换效果(提取奇数放在偶数位上,提取偶数放在奇数位上)
*/
int change(int i) {
int even = i & 0b01010101010101010101010101010101; //偶
int odd = i & 0b10101010101010101010101010101010;//奇
/*
int even = i & 0xaaaaaaaa; //***************************0b二进制,0d十进制,0x十六进制
int odd = i & 0x55555555;
*/
/*
表示2
int even = i&0xaaaaaaaa;//和1010 1010 1010 。。。。运算出偶数位 ,Java中a 1010
int odd = i&0x55555555;//
*/
return (odd>>1)^(even<<1); //10 <--> 01 ,(odd>>1)+(even<<1)也行
}
void QAQ3() {
int a,b;
cin >> a;
b = change(a);
cout << b << endl;
}
/*介于0-1之间的小数可被32位以内二进制精确表示则转换,否则输出ERROR 0.32位(加0.共34位)
默认double 乘积取整法
*/
void QAQ4() {
double num = 0.625;
string sb = "0.";
while (num > 0) {
double r = num * 2;
if (r >= 1) {
sb.append("1");//加1 append在字符串末尾加"..."
num = r - 1;
}
else {
sb.append("0");
num = r;
}
if (sb.length() > 34) {
cout << "ERROR" << endl;
return;
}
}
cout << sb << endl;
}
/*数组中一个数只出现了1次,其他数出现了k次,请输出这个数(练习进制) 简单解法创一个数组对应位加一,最终判断数组中值为1的即出现1次
2个相同的2进制数做加法结果为0,10个相同的10进制数做加法结果为0
**即k个相同的k进制数做加法结果为0 ,输出结果k进制转十进制手工取余法 //java中有现成的
*/
void QAQ5() {//?????????????????1.9课未完成
int a[] = { 2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0 };
int len = (sizeof(a)/4);
char kRadix[100][100]; //保存在二维数组中成3进制并翻转,然后转为字符数组,第一位为低位9 -》 001
int k = 3;
int maxlen = 0;
}
/*第二章 递归 学会评估算法性能 //练习策略循环改递归
*找重复 n阶乘 n*(n-1) n-1的阶乘是原问题的重复,但规模更小-子问题
*找变化 变化的量应该作为参数
*找边界 出口 n = 1时
*/
int jiecheng(int n){
if (n == 1) {
return 1;
}
return n * jiecheng(n - 1);//委托出去的部分收回
}
void QAQ6() {
cout << jiecheng(5) << endl;
}
int main() {
return 0;
}