A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

primarysky

初级黑马

  • 黑马币:21

  • 帖子:5

  • 精华:0

© primarysky 初级黑马   /  2019-3-29 13:38  /  774 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

基础班已经学习了一个多星期了,第一遍程序书写时总是会出现一些书写错误、语法错误和逻辑错误,其次程序有些代码过于冗长,效率不高,举如下按例分析,题目:公鸡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;
                }
            }
        }
    }

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马