题目1:将非负十进制整数n转换成b进制。(其中b=2~16)
分析:
将一个非负十进制整数n转化为b进制。
首先我们可以观察一下二进制的转化:
十进制的n = 10转化为二进制
具体方法是不断的除以2求余数(n%2)。n的变化: n = n / 2。出口就是n为0的时候。(递归出口因此就得到了)
那么我们也知道八进制就是不断的除以8求余数。与二进制一样。十六进制也是如此。只是在余数表达的时候不一样,10以上就是用字母表示10:A , 11:B , 12:C , 13:D , 14:E , 15:F
递归实现:
public static void Binary_Conversion(int n, int b) {
if (n == 0) {
return;
}
Binary_Conversion(n / b, b);
if (n % b >= 10) {
switch (n % b) {
case 10:
System.out.print("A");
break;
case 11:
System.out.print("B");
break;
case 12:
System.out.print("C");
break;
case 13:
System.out.print("D");
break;
case 14:
System.out.print("E");
break;
case 15:
System.out.print("F");
break;
default:
System.out.println("Bug?");
break;
}
} else {
System.out.print(n % b);
}
}
非递归实现:
//非递归实现进制转化
public static String Function2(int n,int b) {
StringBuffer s = new StringBuffer("");
while(n != 0) {
if(n % b < 10) {
s.append(n % b);
}
else {
switch(n % b) {
case 10:
s.append("A");
break;
case 11:
s.append("B");
break;
case 12:
s.append("C");
break;
case 13:
s.append("D");
break;
case 14:
s.append("E");
break;
case 15:
s.append("F");
break;
default:
System.out.println("Bug?");
break;
}
}
n = n / b;
}
return String.valueOf(s.reverse());
}
题目2:任何一个正整数都可以用2的幂次方表示。
例如:
137=2 ^ 7+ 2^ 3 +2 ^0
同时约定幂次方用括号来表示,即ab 可表示为a(b)。
由此可知,137可表示为:
2(7)+2(3)+2(0)
进一步:7= 2 ^ 2+2+2^0 (21用2表示)
3=2+2^0
所以最后137可表示为:
2(2(2)+2+2(0))+2(2+2(0))+2(0)
又如:
1315=2 ^ 10 + 2 ^ 8 +2 ^ 5 +2+2^0
所以1315最后可表示为:
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
输入:正整数(n≤20000)
输出:符合约定的n的0,2表示(在表示中不能有空格)
输入格式 Input Format
一个正整数
输出格式 Output Format
符合约定的n的0,2表示(在表示中不能有空格)
样例输入 Sample Input
73
样例输出 Sample Output
2(2(2)+2)+2(2+2(0))+2(0)
分析:
首先我们一步一步分析,137=27+23+2^0
但是我们要的不是这个结果,最后的结果只能由2,2(0)构成,也就是7,3都要再次分解。所以递归就在此处递归。
一个int型的变量是占4个字节。32个比特位
137的二进制:0000 0000 0000 0000 0000 0000 1000 1001
我们可以从最高为开始遍历,遇到1的时候检测这个1是哪一位,如果为0(最低位)就输出2(0),如果为1位就输出2。(这也是递归的出口条件)
否则就说明不能直接输出,没有分解到最简单的形式。需要继续递归。
注意:只有检测到该位是1的时候才进行操作。因为0不需要计算,0乘以任何数都是0。
检测1的方法:
假设这个数的十进制位n
那么我们要从最高位开始检测,这时候就需要用到移位运算符了。
n>>31这时候已经将最高位移到了最低位。这时候再将其和1按位与就能得到一个数,如果这个数位1,说明最高位是1。如果结果为0,说明最高位是0.
例子:
0000
& 0001(1的二进制)
= 0000(0)
所以满足递归的条件和递归出口我们就都得到了。
public static void Print(int n) {
int first = 1;
for (int i = 31; i >= 0; --i) {
if (((n >> i) & 1) != 0) {
if (first == 1) {
first++;
}
else {
System.out.print("+");
}
if (1 == i) {
System.out.print("2");
}
else if(0 == i){
System.out.print("2(0)");
}
else{
System.out.print("2(");
Print(i);
System.out.print(")");
}
}
}
}
这个题最大的难点就在+号的打印上,一开始怎么都打印不对,要么在开头有加号,要么结尾也有。
最后经过搜索,终于找到一种好的方法。(写博客的时候实在已经找不到那个大佬的网址了,原谅。。)
第一次递归的时候不要打印,以后进行打印,所以就多出来了first变量,然后将递归函数放在最后,那么此时加号就只会被打印在表达式中间,再也不会打印在开头与结尾。
因为每个表达式实际就是一个递归函数的结果。所以递归一次就有个加号,那么把加号的打印放在前面,就不会出现上述的那种结果!