编程新手的疑惑:代码循环如何画出一个简单的三角形

对一个编程新手来说,最先知道了解的莫过于代码执行的三种结构,顺序结构、循环结构和选择结构。

其中个人认为相对难以理解的是循环结构,而针对循环结构的练习题最多的就是循环画出一种简单图形,比如三角形。

当初我在学习写三角形的时候,纯粹是背下来的。那时候去网上找这种打印的资料,都是直接给一个结果,而对于新手而言最重要的分析过程却没有。

这导致很多新手在懵懵懂懂的时候,就学过去了。

个人以为,能够更早的理解并调试循环结构,新手们会更喜欢调试复杂的代码。因此拙文就诞生了。

一、如何打印一个或多行 * 号。

对于新手而言,掌握打印一个 * 号,都是一件极为困难的事情。事实上,打印一个 * 号和打印一个任何教程上都有的 HelloWorld 没有本质的区别。

public class PrintTest {public static void main(String[] args) {System.out.println("*");}
}

对于打印多个 * 号的。有两种方式,一种是 再次写一遍打印代码,二是使用循环条件去控制多次打印。

public class PrintTest {public static void main(String[] args) {System.out.println("*");System.out.println("*");System.out.println("*");}
}
public class PrintTest {public static void main(String[] args) {for (int i = 0; i < 3; i++) {System.out.println("*");}}
}

这两种打印方式的结果是一样的。在调试代码时,会发现,第一种是顺序结构执行,即执行上一句代码后,执行下一句代码;第二种是循环结构执行,当通过循环条件判断时,会执行循环体里的代码,然后再次进行循环条件的判断,当循环条件不满足时,循环结束。

二、如何打印单行多个 * 号。

public class PrintTest {public static void main(String[] args) {for (int i = 0; i < 3; i++) {System.out.print("*");}}
}

这段代码与之前的那个多行 * 号的 代码,只有一点区别。那就是 循环体中  System.out.print()System.out.println()的区别。

为了说明这个的区别,必须先理解面向对象语言的基本概念,对象本身。首先 System是一个对象;out是System对象的一个成员属性,它也是一个对象;print()和println()是out的两个方法,这两个方法均接收一个String类型的对象作为参数,也就是 "*"。这两个方法在打印时有些区别,print()直接输出;println(),先输出,然后再输出一个换行符,也就是说尽管我们只写了 "*",但实际上输出的不只 "*",是因为多输出的那个换行符,导致我们所看到的结果的不同。为了能够清晰的说明这一点,我们可以手动给print()里的参数,加上一个换行符,也就是 "*\n"。

public class PrintTest {public static void main(String[] args) {for (int i = 0; i < 3; i++) {System.out.print("*\n");}}
}

这段代码的打印与之前的打印就一样了。

三、如何打印多行,每行都有多个 * 号。

简单的做法就是结合之前的代码。

public class PrintTest {public static void main(String[] args) {for (int i = 0; i < 3; i++) {System.out.print("*");}System.out.println();for (int i = 0; i < 3; i++) {System.out.print("*");}System.out.println();for (int i = 0; i < 3; i++) {System.out.print("*");}System.out.println();}
}

以上的代码,为了打印多行,首先必须打印单行,为了打印多个,首先必须循环打印,在循环结束后打印一个换行。按照之前的循环逻辑,可以将重复代码转化成循环结构。

public class PrintTest {public static void main(String[] args) {for (int i = 0; i < 3; i++) {for (int i = 0; i < 3; i++) {System.out.print("*");}System.out.println();}}
}

当我们使用如上的代码时,会发现编译报错。 Error:(6, 22) java: 已在方法 main(java.lang.String[])中定义了变量 i

这句话的意思是,重复定义了相同名称的变量i。这就意味着如果我们想转化成循环结构,必须让这两个变量名不同,于是引入j。

public class PrintTest {public static void main(String[] args) {for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {System.out.print("*");}System.out.println();}}
}

这样我们便可打印出我们想要的结果。

四、如何打印多行、每行的 * 号数量等于行号。

这时,我们就需要思考,如何让每行的 * 号数量等于行号。我们可以先简单的列一下。行1,* 1;行2, * 2;行3, *3。那么我们是如何控制每一行的输出内容呢?实际上我们是靠变量j的判断条件,如果j的判断条件变的与行号有关,那么就可以做到了。而行号是由变量i控制的因此我们便有了。

public class PrintTest {public static void main(String[] args) {for (int i = 0; i < 3; i++) {for (int j = 0; j <= i; j++) {System.out.print("*");}System.out.println();}}
}

五、 如何打印多行、每行的 * 号数量等于行号,但每行开始打印的时机不同。

之前的代码,打印出来的结果是每行开始的时候就开始打印,那么如何让它不在开始的时候打印,而是让它往右偏移一下呢。

我们可以引入一个偏移量这个变量offset。若在打印 * 号之前判断这个偏移量,如果到达需要打印的时机,那就打印,那如何没有到达呢? 实际上没有到达时并非是没有字符,只是这个字符是一个空白符" "。这样才能出现这种偏移的效果。

可是这个偏移量是如何定义的呢?我们还是只能先列一下。 行 1, 星 1,偏移 2; 行2, 星 2, 偏移 1; 行3, 星 3,偏移0。看出来了没,就是说偏移量和行号正好是反过来的。而且 行号 + 偏移量 恒等于 3。因此为了定义这个偏移量,必须还要引入一个概念,即我们希望我们打印的 * 号到底有多少行。我们可以引入总行数这个变量line,给它定义为3;偏移量为 line - 行号(i + 1)。我们可以一同引入我们希望打印的 * 每行到底最多有多少个 columns,给它定义为3。

注:尽管一直以来是以行数来做说明,但其实这个偏移量是由columns来控制,行数与星数相同。

public class PrintTest {public static void main(String[] args) {int line = 3;int columns = 3;for (int i = 0; i < line; i++) {int offset = line - (i + 1);for (int j = 0; j < columns; j++) {if (j < offset) {System.out.print(" ");} else {System.out.print("*");}}System.out.println();}}
}

六、如何打印一个标准的正三角形。

上一段代码打印的虽然有偏移,但并非是我们所希望得到的一个标准的正三角形。那么就必须来分析我们目前所达到的效果和我们所预期的有什么样的差异。这些差异又如何通过调整代码来弥补。

为了更加明显的展示差异,我将最大行数和最大列数均定义为9。

        ************************************
*********

至少我们能看出来的是,我们只偏移了左边,而实际上三角形也需要偏移右边。那么我们可以将偏移量分为左偏移和右偏移两个变量。我们同样需要列一下现在的行关系。行1,左偏移 4, 右偏移 4, 星 1;行2, 左偏移3, 右偏移4, 星2;行3,左偏移3,右偏移3,星3...

那么有 loffset 和 roffset 为 (列数columns - 星数line) / 2 。当小于左偏移量和大于等于(列数 - 右偏移量)时,打印 空字符。

public class PrintTest {public static void main(String[] args) {int line = 9;int columns = 9;for (int i = 0; i < line; i++) {int loffset = ( columns - (i + 1 ) ) / 2;int roffset = loffset;for (int j = 0; j < columns; j++) {if (j < loffset) {System.out.print(" ");} else if (j >= (columns - roffset)) {System.out.print(" ");} else {System.out.print("*");}}System.out.println();}}
}

效果为

    *    ***   ***   *****  *****  ******* ******* 
*********
*********

上述代码并没有产生我们所想要的效果。其原因在于,计算偏移量时,无法保证左偏移量和右偏移量始终为整数,因(列数columns - 星数line) 存在 奇数,尽管代码在执行过程中计算为整数,但这会导致计算不精确。

简单的做法就是不打印那些存在奇数的行,也就是说在循环时,若发现列数columns - 星数line 为奇数,则不打印该行。

判断奇数的方法为 求余,如果余数为0,则为偶数,执行循环,如果余数为1,则跳过。

public class PrintTest {public static void main(String[] args) {int line = 9;int columns = 9;for (int i = 0; i < line; i++) {int loffset;int roffset;int odd = (columns - (i + 1 )) % 2;if (odd == 0) {loffset = ( columns - (i + 1 ) ) / 2;roffset = loffset;for (int j = 0; j < columns; j++) {if (j < loffset) {System.out.print(" ");} else if (j >= (columns - roffset)) {System.out.print(" ");} else {System.out.print("*");}}System.out.println();} else {continue;}}}
}

打印效果如下:

    *    ***   *****  ******* 
*********

 

转载于:https://www.cnblogs.com/zixiaoguan/p/7457216.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369471.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解析PHP跳出循环的方法以及continue、break、exit的区别介绍

PHP中的循环结构大致有for循环&#xff0c;while循环&#xff0c;do{} while 循环以及foreach循环几种&#xff0c;不管哪种循环中&#xff0c;在PHP中跳出循环大致有这么几种方式&#xff1a; 代码&#xff1a; <?php$i 1;while (true) { // 这里看上去这个循环会一直执行…

js php 数据类型判断,【js基础】变量类型判断

类型判断方法比较&#xff1a;如果需要想详细了解&#xff0c;请看下文:注&#xff1a;原封不动复制备份&#xff0c;防止删帖在JavaScript中&#xff0c;有5种基本数据类型和1种复杂数据类型&#xff0c;基本数据类型有&#xff1a;Undefined, Null, Boolean, Number和String&…

HTML阻止iframe跳转页面并使用iframe在页面内嵌微信网页版

昨天看到这篇文章[置顶]开源组件NanUI一周年 - 使用HTML/CSS/JS来构建.Net Winform应用程序界面 就想弄一个winform结合html5的一个小东西&#xff0c;突有兴致&#xff0c;想在里面嵌套一个微信网页版。 好了&#xff0c;想法一出来&#xff0c;就行动吧&#xff0c;最终效果…

使用Spring Data Redis进行缓存

在下面的示例中&#xff0c;我将向您展示如何使用Spring Data – Redis项目作为Spring 3.1中引入的Spring Cache Abstraction的缓存提供程序。 我对如何使用Spring的基于Java的配置有很多疑问&#xff0c;因此我将同时提供基于XML和Java的配置供您查看。 依存关系 在此示例中使…

标准模板库(STL)学习指南之set集合

set是关联容器。其键值就是实值&#xff0c;实值就是键值&#xff0c;不可以有重复&#xff0c;所以我们不能通过set的迭代器来改变set的元素的值&#xff0c;set拥有和list相同的特性&#xff1a;当对他进行插入和删除操作的时候&#xff0c;操作之前的迭代器依然有效。当然删…

搜狗语料库数据整编

1 #!/bin/bash2 if [ -z "$1" ] ; then3 echo "请指定输入目录"4 exit 15 elif [ ! -d $1 ] ; then6 echo "[$1]不是一个合法的输入路径"7 exit 18 fi9 if [ -z "$2" ] ; then 10 echo "请指定输出目录" 11 exi…

linux oracle swd.oui,centos7安装oracle11g报错,请问怎么解?

centos7安装oracle11g报错&#xff0c;请问怎么解&#xff1f;在centos7下安装oracle11g到85%时报错提示Error in invoking target install of makefile ins_ctxm.mk查了log提示如下INFO: Start output from spawned process:INFO: ----------------------------------INFO:INF…

CSS布局技巧之——各种居中

居中是我们使用css来布局时常遇到的情况。使用css来进行居中时&#xff0c;有时一个属性就能搞定&#xff0c;有时则需要一定的技巧才能兼容到所有浏览器&#xff0c;本文就居中的一些常用方法做个简单的介绍。 注&#xff1a;本文所讲方法除了特别说明外&#xff0c;都是兼容…

OpenJPA:内存泄漏案例研究

本文将提供完整的根本原因分析详细信息以及解决影响Oracle Weblogic Server 10.0生产环境的Java堆内存泄漏&#xff08;Apache OpenJPA泄漏&#xff09;的方法。 这篇文章还将演示在管理javax.persistence.EntityManagerFactory生命周期时遵循Java Persistence API最佳实践的重…

了解真实的rem手机屏幕适配

rem 作为一个低调的长度单位&#xff0c;由于手机端网页的兴起&#xff0c;在屏幕适配中得到重用。使用 rem 前端开发者可以很方便的在各种屏幕尺寸下&#xff0c;通过等比缩放的方式达到设计图要求的效果。 rem 的官方定义『The font size of the root element.』&#xff0c;…

JDBC查询Oracle全部表名称,如何使用JDBC API从Oracle数据库中的现有表中检索记录?...

您可以使用UPDATE查询来更新/修改表中记录的现有内容。使用此功能&#xff0c;您可以更新表的所有记录或特定记录。语法UPDATE table_nameSET column1 value1, column2 value2...., columnN valueNWHERE [condition];要使用JDBC API更新表中记录的内容&#xff0c;您需要-注…

JUnit与EasyMock合作

开发人员始终需要注意所产生的代码。 在实施新功能或修复某些错误之后&#xff0c;应确保它们能够正常工作。 至少可以借助单元测试来实现。 由于此博客致力于Java编程语言&#xff0c;因此今天我将撰写有关JUnit 4.1和EasyMock 3. 1框架的文章。 这些框架的主要目的是简化单元…

nodejs获取当前url和url参数值

//需要使用的模块 http url 当前url http://localhost:8888/select?aa001&bb002 var http require(http); var URL require(url); http.createServer(function(req, res){var arg url.parse(req.url).query; //方法一arg > aa001&bb002var arg url.parse(…

以A表中的值快速更新B表中记录的方法

1、问题描述 有两张表&#xff0c;A表记录了某些实体的新属性&#xff0c;B表记录了每个实体的旧属性&#xff0c;现在打算用A中的属性值去更新B中相同实体的旧属性&#xff0c;如下图所示&#xff1a; 类似这样的需求&#xff0c;怎样做比较高效呢&#xff1f; 2、制作模拟数…

linux日志文件备份,LINUX 自动备份程序日志(shell)

定期备份脚本案列用tar压缩7天前日志删除7天压缩完日志删除压缩完356天前日志#&#xff01;/bin/bash#delete expire log#script name drop_log#script default remove 7 day log and remove remove archived a year ago#make date 2015/06/15result_clientfind /orafile/app/s…

HTML 网页创建

最简单的方式就是创建一个文本文档&#xff0c;然后将.txt后缀改为.html或者htm。 完成上面的步骤会创建一个完全空白的网页&#xff0c;下面填充一点内容&#xff0c;代码实例如下: <!DOCTYPE html> <html> <head> <meta charset" utf-8">…

Hadoop赠品–综述

各位极客&#xff0c; Packt Publishing关于Apache Hadoop 的书籍赠品已经结束。 您可以在此处找到比赛的原始帖子。 获奖者 将会获得这本书奖的6位幸运获奖者是&#xff08;姓名出现在他们的电子邮件中&#xff09;&#xff1a; Hadoop真实世界解决方案手册 Sellamuthu&…

企业级应用与互联网应用的区别

企业级应用&#xff1a;商业组织、大型企业而创建并部署的解决方案及应用。涉及的外部资源众多、事务密集、数据量大、用户众多、同时必须有较强的安全性考虑。 企业应用和互联网应用从根本来说是相同的&#xff0c;都是基于因特网、HTTP、浏览器的一种应用&#xff0c;但面向的…

hdu-2602 Bone Collector

题目 http://acm.hdu.edu.cn/showproblem.php?pid2602 分析 基础背包问题,有一个容量为V的背包,各种骨头有大小和价值两种属性,求背包能装的骨头的最大价值. AC代码 #include "bits/stdc.h" using namespace std; int val[1010], vol[1010], dp[1010]; int main(int…

linux vfs open函数,Linux VFS中open系统调用实现原理

用户空间的函数在内核里面的入口函数是sys_open通过grep open /usr/include/asm/unistd_64.h查找到的#define __NR_open2__SYSCALL(__NR_open, sys_open)观察unistd_64.h&#xff0c;我们可以猜测用户空间open函数最终调用的系统调用号是2来发起的sys_open系统调用(毕竟glibc一…