题目1:将非负十进制整数n转换成b进制。(其中b=2~16)题目2:任何一个正整数都可以用2的幂次方表示。

题目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变量,然后将递归函数放在最后,那么此时加号就只会被打印在表达式中间,再也不会打印在开头与结尾。
因为每个表达式实际就是一个递归函数的结果。所以递归一次就有个加号,那么把加号的打印放在前面,就不会出现上述的那种结果!

你可能感兴趣的:(Java学习)