Java基础——结构化编程思维
一、题外话
用近十天的时间学习了Java编程的基础知识部分,由于基本是利用工作空闲时间进行的学习,所以进度偏慢。Mars在视频教程中说的很好,慢不怕,贵在坚持,我觉得说的很对,我也希望能够一直坚持下去。
约莫十年前吧,也学过C语言,当时是为了通过计算机三级考试,那会对计算机虽然也是喜欢,但主要是为了找工作增加一个较大的砝码,进行了大量的练习,还总结了一个宝典,被后来参加考试的同学借来借去给弄丢了,想想也挺可惜。而且我是一个忘性比较大的人,过去在电脑应用过程中很多解决问题的办法由于没有记录都逐渐丢失掉了,不然到现在也是一笔比较大的财富。
所以现在尽量把自己的一些感悟和体会用“云”这种现代的方式记录下来,希望可以保持的长久一些。
不管怎么样,从现在开始吧,基础知识看了不少,小程序也看几个,Mars说不要觉得代码简单,看别人写代码和自己写代码是完全不同的两个事情,一定要反复的练,才能熟练并深刻地掌握一门技术,而且编程的关键不是一下把代码就写出来,通常那是一件不可能的事,要把复杂的事分解成一件件简单的事去完成,这样才是正确的编程思维。
很有道理是不是,应用Mars的方法,近期做了两道对高手来看简单的编程题,反复揣摩了一下,也下了点功夫,虽然慢点,但我觉得收获还是颇多,确实体会到了Mars所说的,如果现在就让我直接一次性给这两道题编出来,是万万不可能的,但用Mars的方法,确实都做出来了,蛮兴奋,呵呵。
言归正传,下面我就以这两道题中的一个比较有代表性的例子讲解一下自己的思路,也算记录一下自己的学习轨迹吧。(不想看代码的话直接拉到最后看结论,呵呵)
二、问题的源起
用for循环并调用System.out.print和System.out.println方法来输出下面的图形:
*
***
*****
*******
*****
***
*
要求只能调用System.out.print(“”) System.out.print(“*”)和System.out.println(“*”)这三个方法。
三、解题思路
1.该题目需要创建一个Java类来进行输出,我选择建立一个叫Rhombus的类,并命名为Rhombus.java,为什么叫这个名字呢?因为在编程过程中最好用有意义的英文对类和变量进行命名,这个图形是个菱形,所以就叫Rhombus;
2.把复杂的问题先简单化,先实现输出七行的”*”,每行一个,程序如下:
1 public class Rhombus{ 2 public static void main(String args []){ 3 int i; 4 for(i = 1 ; i <= 7 ; i++){ 5 System.out.println("*"); 6 } //最简单的一个循环,输出7个* 7 } 8 }
3.然后一步步地接近目标,在每行1个”*”的基础上,实现每行7个”*“,程序如下:
1 public class Rhombus{ 2 public static void main(String args []){ 3 int i, j; 4 for(i = 1 ; i <= 7 ; i++){ 5 for(j = 1 ; j <= 6 ; j++){ 6 System.out.print("*"); 7 } //嵌套循环,目的为了输出6个横向的* 8 System.out.println("*"); 9 } //外循环,目的为了输出最后一个*并进行换行 10 } 11 }
4.仔细分析该图形,主要分三个部分,即上面三行,中间三行和下面三行,如果用循环语句输出的话,同步实现比较困难,因此考虑分步实施,即先实现上面四行的输出,第一行输出1个*,第2行输出3个*,以此类推,程序如下:
1 public class Rhombus{ 2 public static void main(String args []){ 3 int i, j, k; 4 for(i = 0 ; i < 4 ; i++){ 5 for(j = 0 ; j < 3 - i ; j++){ 6 System.out.print(" "); 7 } //输出空格,降序输出 8 for(k = 0 ; k < 2 * i ; k++){ 9 System.out.print("*"); 10 } //输出*,由于是递增关系,用2*i来表示,同时要少输出一个 11 System.out.println("*"); 12 } //输出前四行 13 } 14 }
注:此代码较之前的有明显优化,附上第一次写的时候的代码,可读性真差,看来同一题多来几遍还是有效果的啊
1 public class Rhombus{ 2 public static void main(String args []){ 3 int i, j, k; 4 for(i = 1 ; i <= 8 ; i += 2){ 5 for(j = 6 ; j >= i ; j -= 2){ 6 System.out.print(" "); 7 } 8 for(k = 1 ; k < i ; k++){ 9 System.out.print("*"); 10 } 11 System.out.println("*"); 12 } //控制前四行 13 }
5.第4步非常关键,到了这里就可以照猫画虎,把代码颠倒一下,就是后面三行的了,最终的代码如下:
1 public class Rhombus{ 2 public static void main(String args []){ 3 int i, j, k; 4 for(i = 0 ; i < 4 ; i++){ 5 for(j = 0 ; j < 3 - i ; j++){ 6 System.out.print(" "); 7 } //输出空格,降序输出 8 for(k = 0 ; k < 2 * i ; k++){ 9 System.out.print("*"); 10 } //输出*,由于是递增关系,用2*i来表示,同时要少输出一个 11 System.out.println("*"); 12 } //输出前四行 13 14 for(i = 1 ; i < 4 ; i++){ 15 for(j = 1 ; j < i + 1 ; j++){ 16 System.out.print(" "); 17 } //输出空格,升序输出 18 for(k = 6 ; k > 2 * i ; k--){ 19 System.out.print("*"); 20 } //输出*,从多到少输出,所以反过来 21 System.out.println("*"); 22 } //输出后三行 23 } 24 }
四、举一反三
1 public class Rhombus{ 2 public static void main(String args []){ 3 int i = 0; 4 int j, k; 5 while(i < 4){ 6 j = 0; //这里的赋值非常重要,否则循环无法正常进行,下面k是一个道理 7 while(j < 3 - i){ 8 System.out.print(" "); 9 j++; 10 } 11 k = 0; 12 while(k < 2 * i){ 13 System.out.print("*"); 14 k++; 15 } 16 System.out.println("*"); 17 i++; 18 } 19 i = 1; 20 while(i < 4){ 21 j = 1; 22 while(j < i + 1){ 23 System.out.print(" "); 24 j++; 25 } 26 k = 6; 27 while(k > 2 * i){ 28 System.out.print("*"); 29 k--; 30 } 31 System.out.println("*"); 32 i++; 33 } 34 } 35 }
2.用do…while重写代码(超级复杂,看来虽然确实这三种循环可以相互转换,但真的要分不同情况):
1 public class Rhombus{ 2 public static void main(String args []){ 3 int i = 0, j, k; 4 do{ 5 j = 0; 6 do{ 7 System.out.print(" "); 8 j++; 9 } 10 while(j < 4 - i); 11 k = 0; 12 do{ 13 if(k == i * 10000){ //这是没有办法的办法,只要不超过10000行,就没问题,可见有些时候确实不适合用do...while 14 System.out.print(""); 15 } 16 else{ 17 System.out.print("*"); 18 } 19 k++; 20 } 21 while(k < 2 * i); 22 System.out.println("*"); 23 i++; 24 } 25 while(i < 4); 26 27 i = 1; 28 do{ 29 j = 0; 30 do{ 31 System.out.print(" "); 32 j++; 33 } 34 while(j < i + 1); 35 k = 6; 36 do{ 37 if(k == i * 2){ 38 System.out.print(""); 39 } 40 else{ 41 System.out.print("*"); 42 } 43 k--; 44 } 45 while(k > i * 2); 46 System.out.println("*"); 47 i++; 48 } 49 while(i < 4); 50 51 } 52 }
3.继续优化原来的for代码
1 public class Rhombus{ 2 public static void main(String args []){ 3 int i, j, k; 4 for(i = 0; i < 7; i++){ 5 if(i < 4){ 6 for(j = 0; j < 3 - i; j++){ 7 System.out.print(" "); 8 } 9 for(k = 0; k < 2 * i; k++){ 10 System.out.print("*"); 11 } 12 System.out.println("*"); 13 } 14 else{ 15 for(j = 4; j < i + 1; j++){ 16 System.out.print(" "); 17 } 18 for(k = 12 ; k > 2 * i; k--){ 19 System.out.print("*"); 20 } 21 System.out.println("*"); 22 } //加入if...else语句进行控制 23 } 24 } 25 }
4.继续扩展,n行的菱形:
1 import java.util.Scanner; //调用输入包 2 3 public class Rhombus{ 4 public static void main(String args []){ 5 System.out.print("请输入需要打印菱形的行数:"); 6 Scanner scan = new Scanner(System.in); //输入语句 7 int i, j, k; 8 int line = scan.nextInt(); //将输入的语句调用成变量 9 if(line % 2 == 0){ 10 System.out.println("不是合法的行数,请输入奇数行"); 11 } //if条件排除掉不可能的情况 12 else{ 13 for(i = 0; i < line; i++){ 14 if(i < line / 2 + 1){ 15 for(j = 0; j < line / 2 - i; j++){ 16 System.out.print(" "); 17 } 18 for(k = 0; k < 2 * i; k++){ 19 System.out.print("*"); 20 } 21 System.out.println("*"); 22 } 23 else{ 24 for(j = line / 2 + 1; j < i + 1; j++){ 25 System.out.print(" "); 26 } 27 for(k = line * 2 - 2; k > 2 * i; k--){ 28 System.out.print("*"); 29 } 30 System.out.println("*"); 31 } //加入if...else语句进行控制 32 } //将line变量嵌入进各循环中,实现了打印任意行* 33 } 34 35 } 36 }
五、小结:
1.先化繁为简
Java编程一定要把一个个复杂的问题先分解成一个个简单的问题来进行解决,可以用流程图,也可以用思维导图或象我这样的思路条进行分拆,这样一步步地接近最终的结果,我想所有的编程应该都是这个道理;
2.再化简为繁
用一种方法实现程序后,在还不是很精通该知识点的时候,不要怕麻烦,尝试用多种方法,举一反三,往往能消化的更加深刻,一道练习可以温习很多的知识点;
3.Java的基础知识等过一段时间再总结,现在的笔记还不完善,暂时先不发上来了。
PS:第一次写这么长的博客,真累,但挺开心,加油:)