题目一:将非负十进制整数n转换成b进制。(其中b=2~16)
算法设计思路:
将要转换的数字进行除以选择的进制的运算,再用得到的结果除以选择的进制,以此类推,循环下去,直到除法得到的结果为0时结束,将每次余数存在容器中保存。用递归表现出来就是除法得到的结果为0为递归头,此时在保存余数后结束递归。而递归体就是前面所说的除运算以及保存余数的过程。最终容器中存储的数的逆序即为进制转换后的结果。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Test01 {
public static void main(String[] args) {
List<Object> list=new ArrayList<>();//存放进制转换后的结果的容器
int num,k;//输入的数字和选择的进制
Scanner sc=new Scanner(System.in);
System.out.println("请输入你要转换的数:");
num=sc.nextInt();
System.out.println("请输入进制(2-16之间):");
k=sc.nextInt();
exchange(num, k, list);//调用进制转换函数
for(int i=list.size()-1;i>=0;i--) {
System.out.print(list.get(i));
}
sc.close();
}
//进制转换函数
public static void exchange(int num,int k,List<Object> list) {
if(num/k==0) {//结束递归
list.add(num%k);
return;
}else {
if(k==16&&(num%k)>=10) {//如果选择的的进制是16
switch(num%k) {
case 10:
list.add("A");
break;
case 11:
list.add("B");
break;
case 12:
list.add("C");
break;
case 13:
list.add("D");
break;
case 14:
list.add("E");
break;
case 15:
list.add("F");
}
}else {
list.add(num%k);
}
num=num/k;
exchange(num,k,list);//递归调用
}
}
}
题目二:
任何一个正整数都可以用2的幂次方表示。例如
137=27+23+2^0
同时约定幂次方用括号来表示,即ab 可表示为a(b)。
由此可知,137可表示为:
2(7)+2(3)+2(0)
进一步:7= 22+2+20 (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)
算法设计思路:
将要转换成相应格式的数字先用上面题目一的方法转换成其二进制结果的倒序,刚好容器中的下标i越大表示越高位。调用递归函数,递归体如下,将二进制结果中为1的位取出来,比如下标为m、n、k处的数字为1,则该数的中间表示结果为2(m)+2(n)+2(k),根据m、n、k是否大于1进行相应的选择处理,若大于1,先将边上的2和括号进行打印,然后再进行m、n、k的二进制的倒序转换,然后递归调用此函数自己,对m、n、k进行分解,若小于1则进行直接相应的打印输出。后面的过程如此类推。当分解的数字小于8时,则表示可以用2(2)、2、2(0)进行组合来表示出该数字,此处也即为递归头,在递归头里面进行相应的打印操作处理,完了以后该递归结束。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Test02 {
public static void main(String[] args) {
List<Integer> list=new ArrayList<>();//定义容器list存储输入的数字转换后的二进制数
int num;//输入的数
Scanner sc=new Scanner(System.in);
while(true) {
System.out.println("请输入小于20000的正整数:");
num=sc.nextInt();
if(num>20000||num<=0) {//不符合要求重新输入
System.out.println("输入数据错误,请按要求输入:");
}else {
break;
}
}
exchange_2(num,list);//将数字转换成二进制数
exchange_1(list);//进行转换运算
sc.close();
}
//向要求格式转换的函数
public static void exchange_1(List<Integer> list) {
if(list.size()==1&&list.get(0)==1) {//输入的数字为1的时候
System.out.println("2(0)");
return;
}
if(list.size()<=3) {//当该数字小于8时,进行具体的分解
if(list.size()==3) {//该数字小于8且大于或者等于4
for(int i=list.size()-1;i>=0;i--) {
if(list.get(i)==1&&i==(list.size()-1)) {
System.out.print("2(2)");
}else if(list.get(i)==1&&i==list.size()-2){
System.out.print("+2");
}else if(list.get(i)==1&&i==list.size()-3){
System.out.print("+2(0)");
}
}
}else if(list.size()==2) {//该数字小于4且大于或者等于2
for(int i=list.size()-1;i>=0;i--) {
if(list.get(i)==1&&i==list.size()-1) {
System.out.print("2");
}else if(list.get(i)==1&&i==list.size()-2) {
System.out.print("+2(0)");
}
}
}else {//该数字小于2且大于或者等于0
if(list.get(0)==1) {
System.out.print("2");
}else{
System.out.print("2(0)");
}
}
return;
}else {//该数字大于等于8
for(int i=list.size()-1;i>=0;i--) {//对该数字二进制结果的每一位进行判断
if(list.get(i)==1) {//二进制的第i位为1表示该数字的非最终的表示结果里有2(i),这个结果后面可能还会被分解
if(i>1) {
List<Integer> temp=new ArrayList<Integer>();
if(i==list.size()-1) {
System.out.print("2(");
}else {
System.out.print("+2(");
}
exchange_2(i, temp);//将i进行二进制的转换
exchange_1(temp);//对i再进行更具体化的分解
System.out.print(")");
}else {//当i==0或者1的时候,直接进行输出
if(i==1) {
System.out.print("+2");
}else{
System.out.print("+2(0)");
}
}
}
}
}
}
//向二进制转换的函数
public static void exchange_2(int num,List<Integer> list) {
if(num/2==0) {//结束递归
list.add(num%2);
return;
}else {
list.add(num%2);//将二进制的每一位添加进容器list中
num=num/2;
exchange_2(num,list);//递归调用
}
}
}