#include<stdio.h>
#include<iostream>
using namespace std;
void PrintToLow1(int num);//7.对十进制数 从高到低输出各位数字
void PrintToLow2(int num);
void PrintToHigh1(int num);
void PrintToHigh2(int num);//对十进制数 从低到高输出各位数字
void MakeUpOfTwo(int num, int r);//8.任何一个正整数都可以用2 的幂次方来表示
void ExtendMakeUpOfTwo(int num, int r);
void Choose1(int n, int r);//9.从n个数中取r个数的组合满足组中的数互不相同且前面的数小于后面的数
void Choose2(int n, int r);
int divide[100] = {0};
int record[100];
int main()
{
cout << "\n从低位开始打印(递归):\n";
PrintToLow1(34673);
cout << "\n从低位开始打印(迭代):\n";
PrintToLow2(34673);
cout << "\n从高位开始打印(递归):\n";
PrintToHigh1(34673);
cout << "\n从高位开始打印(迭代):\n";
PrintToHigh2(34673);
cout << "\n任何一个正整数都可以用2 的幂次方来表示" << endl;
MakeUpOfTwo(1315, 0);
cout << "\n任何一个正整数都可以用2 的幂次方来表示" << endl;
ExtendMakeUpOfTwo(1315, 0);
cout << "\n组合数:\n";
Choose1(5, 3);
record[0] = 3;
cout << "\n组合数:\n";
Choose2(5, 3);
}
void PrintToLow1(int num)
{
if(num == 0)
return;
PrintToLow1(num / 10);
printf("%d ", num % 10);
}
void PrintToLow2(int num)
{
int record[10], i = 0;
while(num)
{
record[i++] = num % 10;
num /= 10;
}
i--;
for(;i >= 0; i--)
printf("%d ", record[i]);
}
void PrintToHigh1(int num)
{
if(num == 0)
return;
printf("%d ", num % 10);
PrintToHigh1(num / 10);
}
void PrintToHigh2(int num)
{
while(num)
{
printf("%d ", num % 10);
num /= 10;
}
}
//整个求解过程相当于 十进制到二进制的转换 采用辗转相除法
void MakeUpOfTwo(int num, int r)
{
if(num == 1)
cout << "2(" << r << ")";
else
{
MakeUpOfTwo(num / 2, r + 1);//用r记录递归的深度 即2的r次幂
if(num % 2 == 1)//此时递归已经全部结束开始一层层的返回
{//相当于用二进制表示十进制的数 只有该位对应为1则1*2^n 余数为1对应辗转相除法中 /2 余1写在后面
cout << " + 2(" << r << ")";
}
}
}
void ExtendMakeUpOfTwo(int n, int r)
{//n=1对应的是一组递归的终结
if(n == 1)//当n=1时证明初始的n已经无法在进行分割了
{
switch(r)
{
case 0:
printf("2(0)");
break;
case 1:
printf("2(1)");
break;
case 2:
printf("2(2)");
break;
default:
printf("2(");
ExtendMakeUpOfTwo(r, 0);//函数ExtendMakeUpOfTwo(n, 0)的作用就是求n的2的幂次方的表示
//因此直接递归调用就可以将之前的2以上的幂的次数表示转换成更小的组成
printf(")");//递归结束之后将括号补齐
}
}
else
{
ExtendMakeUpOfTwo(n / 2, r + 1);//持续递归 最后一次递归一定执行的是上方的if语句
if(n % 2 == 1)//开始逐层返回
{
switch(r)
{
case 0:
printf("+2(0)");
break;
case 1:
printf("+2(1)");
break;
case 2:
printf("+2(2)");
break;
default://在本函数中不允许有超过2的2的幂次的表示 因此如果出现就要继续递归
printf("+2(");
ExtendMakeUpOfTwo(r, 0);
printf(")");
}
}
}
}
void Choose1(int n, int r)
{
cout << endl;
int counts = 0;
for(int i = 1; i <= n - 2; i++)
{
for(int j = i + 1; j <= n - 1; j++)
{
for(int k = j + 1; k <= n; k++)
{
counts++;
printf("%d, %d, %d;\n", i, j, k);
}
}
}
}
void Choose2(int n, int r)
{
for(int i = n; i >= r; i--)
{
record[r] = i;
if(r > 1)
Choose2(i - 1, r - 1);
else
{
for(int j = record[0]; j > 0; j--)
printf("%d ", record[j]);
cout << endl;
}
}
}