一、题目
任何一个正整数都可以用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)
二、题目分析
该题目可以使用递归算法来实现,设计一个拥有这样功能的函数:将一个正整数作为函数的实参,它可以将这个数写成a(X)+b(Y)+c(Z)+…的形式,创建一个字符串数组,将上面的式子存入到数组中,其中X,Y,Z是一个正整数或者是0,然后再查找每一个数组的元素,只要不是“2”、“0”、“(”、“)”的元素,将其从字符串转化为整型,然后这个数再次调用函数本身,这样的话就会循环的将字符串数组中的元素全部转化为题目要求的形式。
我刚开始做这道题目时,忽略了题目中第六行的“(21用2表示)”,导致我的算法中将2转化为2(1)再转化为2(2(0))与题目中的意思不符,后来还是发现了这个问题并给予了改正,所以这道题目中我的输出结果有两个:一个是按照题目要求的形式,另一种是将幂指数“1”转化为2(0),也就是最终2将会以2(2(0))形式出现。
三、算法分析
递归算法实现:
函数fun(int temp)将传入函数的实参temp转化为a(X)+b(Y)+c(Z)+…的形式并存入到字符串数组中
然后去遍历字符串数组:
for(int j=0;j<=sum;j++) {
if(!arr[j].equals("2")&&arr[j]!="("&&arr[j]!=")"&&arr[j]!="+"&&!arr[j].equals("0")) {
int tem=Integer.valueOf(arr[j]);
return fun(tem,j);
}
递归出口:遍历字符串数组中所有的元素,如果没有需要转化的元素则,返回0,递归结束。
四、程序源代码(只给出按照题目要求的代码,如有需要另外一个输出结果的源码联系我)
import java.util.Scanner;
public class fun {
static int sum=-1;
static String[]arr=new String[100];
static int fun2(int temp,int k) throws Exception{
int m=0;
String[]t=new String[100];
while(temp!=0) {
int i=14;
while(i>=0) {
if(Math.pow(2, i)<=temp) { //循环判断符合的幂指数
temp=temp-(int)Math.pow(2, i);
if(m==0) { //存入符合要求的格式
t[m++]="2";
t[m++]="(";
t[m++]=String.valueOf(i);
t[m++]=")";
if(i==1)
m=m-3;
i--;
}
else {
t[m++]="+";
t[m++]="2";
t[m++]="(";
t[m++]=String.valueOf(i);
t[m++]=")";
if(i==1)
m=m-3;
i--;
}
}
else {
i--;
}
}
}
for(int n=sum,i=sum-k;i>0;n--,i--) { //将需要转化的字符串元素后面的元素整体向后移动m-1个
arr[n+m-1]=arr[n];
}
if(sum!=-1)
sum--;
for(int j=k,l=0;l<m;l++,j++) { //将转化后的字符串元素存入到字符串中
arr[j]=t[l];
sum++;
}
for(int j=0;j<=sum;j++) { //遍历寻找需要转化的字符串元素
if(!arr[j].equals("2")&&arr[j]!="("&&arr[j]!=")"&&arr[j]!="+"&&!arr[j].equals("0")) {
int tem=Integer.valueOf(arr[j]);
return fun2(tem,j);
}
}
return 0;
}
public static void main(String[]args) {
int i=0;
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个正整数");
i=scanner.nextInt();
try{
fun2(i,0);
}catch(Exception e) {}
for(i=0;i<=sum;i++) {
System.out.print(arr[i]);
}
}
}
五、测试以及运行结果
六、总结
在这次程序设计过程中,遇到了一些问题,输出结果与题目要求不一致,最后发现自己忽略了题目中的要求“2(1)写为2”,最终也是改正了,这道题目对我来说比较困难的是对字符串数组的操作,要将一个数转化为题目要求的形式,经常会出现意料之外的输出,经过本次练习,对这样的递归还有字符串数组的操作积累了经验,再接再厉。