递归程序设计

一、题目要求

题目1:将非负十进制整数n转换成b进制。(其中b=2~16)
题目2:任何一个正整数都可以用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)

二、程序分析

题目一

递归模型:

在这里插入图片描述

递归栈:

在这里插入图片描述

题目二

递归模型:

在这里插入图片描述

递归树:

在这里插入图片描述

三、调试

题目一:

在这里插入图片描述
在这里插入图片描述

题目二:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

四、运行结果

题目一:

在这里插入图片描述

当输入为负数时:

在这里插入图片描述

题目二:

在这里插入图片描述

五、总结

1.递归的基本思想就是把规模大的问题转化为规模小的相似的子问题来解决
在这里插入图片描述
2.练习了递归与非递归之间的转化

三种实现方法:
① 采用迭代解法
如果一个函数或过程的递归关系树退化为线性的,那么该函数或过程就比较容易使用迭代的方法实现
② 末尾递归消除
如果递归调用语句时过程或函数的最后一句可执行语句,这样的调用称为末尾递归调用
③ 使用堆栈

3.在做第一题时,题目中有一句“如果输入为负数时,将不再计算”。
处理这种问题时,这次使用了自定义异常:
① 自定义该异常类继承Exception或其子类
② 在构造方法中,显示用super来调用父类的构造方法

class FushuException extends Exception {
public FushuException() {
super();
System.out.println(“要进行进制转换的数字不能为负数”);
}
}

六、代码

//非递归

import java.util.Scanner;

public class One {

	private static StringBuffer change(int num, int format) {
		StringBuffer sb = new StringBuffer();
		if (format > 1 && format < 10) {
			int m = num % format, n = num / format;
			sb.append(m);
			while (n != 0) {
				m = n % format;// 余数
				n = n / format;// 商
				sb.append(m);
			}
			return sb.reverse();
		} else if (format > 10 && format < 17) {
			int m = num % format, n = num / format;
			sb.append(m);
			while (n != 0) {
				m = n % format;// 余数
				n = n / format;// 商
				if ((m > 9) && (m < format)) {
					switch (m) {
					case 10:sb.append("A");break;
					case 11:sb.append("B");break;
					case 12:sb.append("C");break;
					case 13:sb.append("D");break;
					case 14:sb.append("E");break;
					case 15:sb.append("F");break;
					}
				} else {
					sb.append(m);
				}
			}
			return sb.reverse();
		}
		return sb;

	}

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		int p, q;
		try {
			p = sc.nextInt();// 输入要进行进制转换的数字
			q = sc.nextInt();// 转换的进制位数
			sc.close();
			if (p < 0) {
				throw new FushuException();
			}
			System.out.print(p + "转换的" + q + "进制为:");
			System.out.println(change(p, q));
		} catch (FushuException e) {
			e.getMessage();
		}
	}
}

class FushuException extends Exception {
	public FushuException() {
		super();
		System.out.println("要进行进制转换的数字不能为负数");
	}
}
//递归

import java.util.Scanner;

public class One {

	private static int change(int num, int format) {
		StringBuffer sb = new StringBuffer();
		try {
			if ((format > 9) && (format <= 16)) {// 10-16进制时
				int m, n;
				m = num % format;// 余数
				n = num / format;// 商
				if (n != 0) {
					if ((m > 9) && (m < format)) {
						switch (m) {
						case 10:sb.append("A");break;
						case 11:sb.append("B");break;
						case 12:sb.append("C");break;
						case 13:sb.append("D");break;
						case 14:sb.append("E");break;
						case 15:sb.append("F");break;
						}
					} else {
						sb.append(m);
					}
					return change(n, format);
				} else {
					sb.append(m);
					return m;
				}
			} else {// 2~9进制
				int m, n;
				m = num % format;// 余数
				n = num / format;// 商
				if (n != 0) {
					sb.append(m);
					return change(n, format);
				} else {
					sb.append(1);
					return 1;// 当n=0,递归出口
				}
			}
		} finally {
			System.out.print(sb.reverse());// 得到的余数序列反转
		}
	}

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		int p, q;
		try {
			p = sc.nextInt();// 输入要进行进制转换的数字
			q = sc.nextInt();// 转换的进制位数
			sc.close();
			if (p < 0) {
				throw new FushuException();
			}
			System.out.print(p + "转换的" + q + "进制为:");
			change(p, q);
		} catch (FushuException e) {
			e.getMessage();
		}
	}
}

class FushuException extends Exception {
	public FushuException() {
		super();
		System.out.println("要进行进制转换的数字不能为负数");
	}
}
//递归

import java.util.Scanner;

public class Two {

	public static void main(String[] args) {
		String str = "";
		Scanner scan = new Scanner(System.in);
		int num = scan.nextInt();
		scan.close();
		System.out.println(pow(num, str)); 
	}

	private static String pow(int num, String str){
		int p= 1, n = 0;
		if(num==1){//当num=1,递归出口
		return "2(0)";
		}else if(num==2){//当num=2,递归出口
		return "2";
		}

		while(p*2<=num){//求出离num最大的n平方数
			p *= 2;
			++n;
		}
		if(num - p != 0){
			int diff = num-p;//num减去离它最大的n平方数
			str = "2("+pow(n,str)+")+"+ pow(diff,str); 
		}else{
			str = "2("+pow(n,str)+")";
		}
		str = str.replace("2(2(0))", "2");
		return str;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值