基础班已经学习了一个多星期了,第一遍程序书写时总是会出现一些书写错误、语法错误和逻辑错误,其次程序有些代码过于冗长,效率不高,举如下按例分析,题目:公鸡1只5钱,母鸡1只3钱,小鸡3只1钱,100钱买100只鸡怎么买?
这是我第一遍书写的代码:
public class Test2 {
public static void main(String[] args) {
int i = 0;
int j = 0;
int k = 0;
for (; i <= 100; i++) {
for (; j <= 100; j++) {
for (; k <= 100; k++) {
if (i + j + k == 100 && 5 * i + 3 * j + 1 / 3 * k == 100) {
System.out.println("公鸡数为:" + i);
System.out.println("母鸡数为:" + j);
System.out.println("小鸡数为:" + k);
continue;
}
}
}
}
}
}
因为用IDEA编写,所以过程中书写错误已经改正。
思路:先定义三个整数i, j, k存放小鸡数量,然后,用三个互相嵌套的for循环来分别对三个参数遍历,因为之前定义过i,j,k的初始值,所以for循环初始值省略,3种鸡的总和100,所以边界值为100,如果符合i + j + k == 100并且5 * i + 3 * j + 1 / 3 * k == 100则把3种鸡数量记录下来。
接下来
第一次运行程序:没有报错,但控制台上什么也没有。
Debug分析,没有输出结果,说明循环没有进入if语句,断点在if语句上,循环发现,i=0,j=0,k=100时跳出循环,但当i=0,j=1时,k还是100,原来是最内层循环结束后k的值没有重新初始化,思考后,把int j=0;和int k=0的放进for语句中,这样里面的两个循环变成:
for (int j=0; j <= 100; j++) {
for (int k=0; k <= 100; k++) {
第二次运行程序: 控制台出现了N组数据,第一组结果是:
公鸡数为:2
母鸡数为:30
小鸡数为:68
检测数据发现不对,2*5+30*3+68/3 = 122.7,而2*5+30*3=100,马上发现是1/3*k的问题,根据整数相除原理1/3结果为0,所以这里把1/3改为1.0/3,自动转化为double类型。
第三次运行结果:控制台出现4组数据,检测都正确。
程序逻辑通过后,接下来对程序进行瘦身和效率提升,因为本程序中用的是3个for嵌套循环,边界都是100,所以它的循环次数是100*100*100=1000000次,那么第一个问题是能不能把100的值改小,第二个问题能不能通过两个甚至一个for循环就可以解决问题?
第一个问题:公鸡的边界值,因为公鸡的单价是5,而总价格不能超过100,很明显隐含的条件是公鸡总数不会超过100/5=20,所以这里把i<=100改为i<=20,同理j <= 100改为j <= 33,而k的值必需是3的倍数才行,所以k的步进条件k++改为k +=3,改完条件和步进语句后,程序总循环次数为20*33*33=21780次,提高了50倍效率。
第二个问题:能不能减少for的个数?考虑到这里的条件是i+j+k=100,那么k=100-i-j,所以这里把第三个循环取消,改进后的循环次数为20*33=660次,再次提高了33倍效率。
总结:编程过程中逻辑思维是平时做题养成的,逻辑细节可以通过Debug来调整,但一个程序的效率和复杂性是需要通过思考来改进的,这就要我们更明白程序运行的顺序结构和原理,打好基础知识是非常重要的。
附:修改后的代码:
public class Test2 {
public static void main(String[] args) {
int i = 0;
int k = 0;
for (; i <= 20; i++) {
for (int j = 0; j <= 33; j++) {
k = 100 - i - j;
if (k % 3 == 0 && 5 * i + 3 * j + k / 3 == 100) {
System.out.println("公鸡数为:" + i);
System.out.println("母鸡数为:" + j);
System.out.println("小鸡数为" + k);
System.out.println("-------------");
continue;
}
}
}
}
|
|