一、题目:
二、递归方式实现:
2.1.实现思路解析: 先用笔写出花1元可以得到1瓶汽水, 花2元可以得到5瓶汽水,花3元可以得到11瓶汽水, 花4元可以得到17瓶汽水, 花5元可以得到23瓶汽水,
发现规律: 花1块钱可买到1瓶汽水不符合通用规则,花2块钱可得到5瓶汽水不符合通用规则,
花3块钱可得到11瓶汽水不符合通用规则(比第二次可得到的汽水数多6瓶),
花4块钱可得到17瓶汽水不符合通用规则(比第三次可得到的汽水数多6瓶),
花5块钱可得到23瓶汽水不符合通用规则(比第四次可得到的汽水数多6瓶)。
写出如下递归代码:
花n元得到的汽水总数用num(int n)方法来计算。
花1块钱得到的汽水数是1,花1块钱得到的汽水数是5, 后边花第n块钱的汽水数为 num(n-1) + 6;
2.2.代码实现:
public static void main(String[] args) { System.out.println(num(20)); } private static int num(int n) { if(n==1){ return 1; }else if(n==2){ return 5; }else{ return num(n-1) + 6;//用num(20)调用本方法时,返回num(19) + 6, }//则又要执行num(19)再次调用本方法,返回num(18) + 6, //则又要执行num(18)再次调用本方法,返回num(17) + 6, //则又要执行num(17)再次调用本方法,返回num(16) + 6, //经过多次执行num(int n),直到n=4时,执行num(4)来再次调用本方法,返回num(3) + 6 则又要执行num(3)再次调用本方法, //执行num(3)来再次调用本方法,返回num(2) + 6 (即返回11), 则上边的每一项都知道返回值了(可以快速计算一下: 11+ 差值6 * 17个表达式,答案是113) }
三、普通while循环的方式实现:
3.1.简析:
用笔罗列出花1元,花2元,花3元,花4元分别得到的 汽水总数, 然后归纳每一小步,并将每一小步对应的代码写到while循环中(不用总结通用表达式)(此方式代码相对递归方式复杂一些,所以用递归方式更合适)。
3.2.代码实现:
//本方案是根据业务需求,用循环一次花一元购买汽水之后就判断是否可以用瓶子或瓶盖兑换新汽水,直到无法兑换就再花一元购买新汽水,直到花掉20元结束。 //写出的代码(不是用笔罗列出花费前几块钱购买的汽水数及每次兑换的汽水 情景, 然后总结通用表达式) public static void main(String[] args) { //一、定义案例中的所有变量并初始化 //money为当前循环花的钱, allMoney为总共需要花掉的钱 int money=1, allMoney=20; int bottles=1;//bottles为当前剩余的瓶子数(兑换过的瓶子被回收掉, bottles为剩余没有兑换的瓶子) int caps=1;//caps为剩余瓶盖数(兑换过的瓶盖被回收掉, caps为剩余没有兑换的瓶盖) int count=1;//count为总共得到的汽水数 int i=0; //变量i用来观察循环次数的,本案例中可以删除变量i //二、用循环:2.1.看能否兑换新汽水, 2.2.不能兑换就将money+1再购买一瓶新汽水 while(true){ i++; //2.1.看能否兑换新汽水 if(bottles >= 2){ count = count + bottles/2; caps= bottles>2? caps+bottles/2 : caps+1; bottles= bottles>2?bottles%2+1: 1; } if(caps >= 3){ count = count + caps/3; bottles= caps>3? bottles+caps/3 : bottles+1; caps= caps>3? caps % 3+1 : 1; } //2.2.不能兑换就将money+1再购买一瓶新汽水 if(bottles != 2 && caps != 3){ money++; if(money>allMoney){//如果花费的总钱数超过20元就结束程序(表示20元全部用完了) break; }else{ count++; bottles++; caps++; } } } //三、打印总共得到的汽水总数count。 System.out.println(count); }
四、代码备份:
4.1.递归方式代码:
private static int num(int n) { if(n==1){ return 1; }else if(n==2){ return 5; }else{ return num(n-1) + 6;//用num(20)调用本方法时,返回num(19) + 6, }//则又要执行num(19)再次调用本方法,返回num(18) + 6, //则又要执行num(18)再次调用本方法,返回num(17) + 6, //则又要执行num(17)再次调用本方法,返回num(16) + 6, //经过多次执行num(int n),直到n=4时,执行num(4)来再次调用本方法,返回num(3) + 6 则又要执行num(3)再次调用本方法, //执行num(3)来再次调用本方法,返回num(2) + 6 (即返回11), 则上边的每一项都知道返回值了(可以快速计算一下: 11+ 差值6 * 17个表达式,答案是113) } public static void main(String[] args) { int rs=num(1);//花1元 System.out.println(rs);//1//可以买1瓶汽水 //花1元不符合下边的数学规律,不能将结果书写为表达式 rs=num(2);//花2元 System.out.println(rs);//5//可以买5瓶汽水//花2元不符合下边的数学规律,不能将结果书写为表达式 rs=num(3);//花3元 System.out.println(rs);//11//可以买11瓶汽水 //总钱数为3可买汽水 比 总钱数为2可买汽水 多6瓶 :num(3-1)+6 rs=num(4);//花4元 System.out.println(rs);//17//可以买17瓶汽水 //总钱数为4可买汽水 比 总钱数为3可买汽水 多6瓶 :num(4-1)+6 rs=num(5);//花5元 System.out.println(rs);//23//可以买23瓶汽水 //总钱数为5可买汽水 比 总钱数为4可买汽水 多6瓶 :num(5-1)+6 int n=20; rs=num(n);//花20元 System.out.println(rs);//113//可以买113瓶汽水 //假设花费总钱数为n, 则购买的汽水总数为: num(n-1) + 6 }
4.2.while循环方式:
下边代码又详细注释:
//本方案是根据业务需求,用循环一次花一元购买汽水之后就判断是否可以用瓶子或瓶盖兑换新汽水,直到无法兑换就再花一元购买新汽水,直到花掉20元结束。 //写出的代码(不是用笔罗列出花费前几块钱购买的汽水数及每次兑换的汽水 情景, 然后总结通用表达式) public static void main(String[] args) { //一、定义案例中的所有变量并初始化 //money为当前循环花的钱, allMoney为总共需要花掉的钱 //(核心循环逻辑: 循环时看能否兑换新汽水,不能兑换就将money+1再购买一瓶新汽水,再次循环看能否兑换新汽水,如此一直循环直到money>20结束) int money=1, allMoney=20; int bottles=1;//bottles为当前剩余的瓶子数(兑换过的瓶子被回收掉, bottles为剩余没有兑换的瓶子) int caps=1;//caps为剩余瓶盖数(兑换过的瓶盖被回收掉, caps为剩余没有兑换的瓶盖) int count=1;//count为总共得到的汽水数 //二、用循环: //2.1.看能否兑换新汽水, 2.2.不能兑换就将money+1再购买一瓶新汽水 //(剩余未兑换的瓶子数>=2就兑换新汽水<汽水总数增加count = count + bottles/2, >,否则就继续购买新汽水) //再次循环看能否兑换新汽水,如此一直循环直到money>20结束 while(true){ //2.1.看能否兑换新汽水 if(bottles >= 2){//2.1.1.如果剩余未兑换的瓶子数bottles>=2就兑换新汽水 //A.汽水总数增加(汽水总数=汽水总数+剩余未兑换的瓶子数/2) (比如bottles=4,则 count=count+ 4/2,表示一次用4个瓶子兑换两瓶汽水,汽水总数加2) count = count + bottles/2; //caps++; //B.剩余未兑换的瓶盖数增加(剩余未兑换的瓶子数bottles>2的话,就让剩余瓶盖caps=caps+bottles/2,比如bottles=4则caps=caps+4/2。 否则caps=caps+1) caps= bottles>2? caps+bottles/2 : caps+1; //C.更新剩余未兑换的瓶子数: // C1.如果剩余未兑换的瓶子数bottles>2,就将bottles更新为bottles%2 + bottles/2 (本次剩余的未兑换的瓶子数 + 本次兑换的新汽水瓶子数) // (比如剩余未兑换的瓶子数bottles为3瓶,则可以用其中两瓶兑换一瓶新汽水, // 则总共剩余未兑换的瓶子数=剩余1瓶未兑换的瓶子数bottles%2即3%2 + 本次兑换的新汽水瓶子数bottles/2即3/2 ) bottles= bottles>2? bottles%2+ bottles/2 : 1; } if(caps >= 3){//2.1.3.如果剩余未兑换盖子数caps >= 3就兑换新汽水 //A.汽水总数增加(汽水总数=汽水总数+剩余未兑换盖子数caps/3) (比如caps=7,则 count=count+ 7/3,表示一次用7个瓶子兑换两瓶新汽水,汽水总数加2) count = count + caps/3; //bottles++; //B.剩余未兑换的瓶子数增加(剩余未兑换的盖子数caps>3的话,就让剩余瓶子数bottles+caps/3,比如caps=7则bottles=bottles+7/3。 否则bottles=bottles+1) bottles= caps>3? bottles+caps/3 : bottles+1; //C.更新剩余未兑换的盖子数: // C1.如果剩余未兑换的盖子数caps>3,就将caps更新为caps % 3+ caps/3 (本次剩余的未兑换的盖子数 + 本次兑换的新汽水盖子数) // (比如剩余未兑换的盖子数caps为4瓶,则可以用其中三个瓶盖兑换一瓶新汽水。 // 则总共剩余未兑换的瓶盖数=剩余1瓶未兑换的盖子数caps%3即4%3 + 本次兑换的新汽水盖子数caps/3即4/3 ) caps= caps>3? caps%3 + caps/3 : 1; } //2.2.不能兑换就将money+1再购买一瓶新汽水 //(花费的总钱数加1, 如果花费的总钱数超过20元就结束, 否则得到的总汽水数count加1, 剩余未兑换的瓶子数bottles+1, 剩余未兑换的盖子数caps+1) if(bottles != 2 && caps != 3){ money++;//A.花费的总钱数加1 if(money>allMoney){//B.如果花费的总钱数超过20元就结束程序(表示20元全部用完了) break; }else{//否则 count++;//C.得到的总汽水数count加1, bottles++;//D.剩余未兑换的瓶子数bottles+1 caps++;//E.剩余未兑换的盖子数caps+1 } } } //三、打印总共得到的汽水总数count。 System.out.println(count); }
标签:count,汽水,bottles,caps,案例,num,经典,兑换 From: https://www.cnblogs.com/zhaoyongqi/p/18184008