龙空技术网

cqh-流程控制语句

分享的熊 86

前言:

眼前姐妹们对“java 输入输出能变颜色吗”大约比较着重,兄弟们都想要了解一些“java 输入输出能变颜色吗”的相关知识。那么小编同时在网摘上收集了一些关于“java 输入输出能变颜色吗””的相关文章,希望各位老铁们能喜欢,朋友们快快来了解一下吧!

6. 流程控制语句

求职,任意,请联系我,能敲电脑就行。

内容导视:

输入与输出分支控制语句循环控制语句转向控制语句6.1 输入与输出

内容导视:

接收键盘输入普通输出格式化输出输出不同颜色的文字6.1.1 接收键盘输入

我们需要用到 java.util 包下的 Scanner 类,非 lang 包下的类需要导入,在首行加入 import 完整类名;

 import java.util.Scanner;  public class Hello {     public static void main(String[] args) {         // 创建一个扫描仪实例,扫描指定输入流产生的值(System.in 流对应于键盘输入)         Scanner scanner = new Scanner(System.in);                  System.out.print("等待你的输入,请按下任意键:");                  // 等待输入字符串,使用 String 类型的变量 name 接收         String name = scanner.next();         System.out.println("你输入的字符串为:" + name);                  System.out.print("等待你输入整数:");                  // 等待输入整数,使用 int 类型的变量 num 接收         int num = scanner.nextInt();         System.out.println("你输入的整数为:" + num);                  /*             scanner.nextDouble() 是接收小数             scanner.next().charAt(0) 是接收字符         */     } }

不想输入,请按 Ctrl + C 结束程序。

注意,让你输入整数时,你却输入了其它类型的字符,会报 java.util.InputMismatchException 输入不匹配异常。

可以使用如下方法避免:

 System.out.print("等待输入中:"); // 如果输入的是整数,此方法会返回 true,执行第一条分支 if (scanner.hasNextInt()) {     int num = scanner.nextInt();     System.out.println("你输入的是个整数:" + num); } else {     System.out.println("你输入的不是整数"); }

以下内容可跳过

可以自定义 Readable 的实现类,next 方法内部会调用 getCompleteTokenInBuffer 方法以空格为分隔点读取字符串缓冲区 cb 中的内容,返回的内容称为 token;

当 cb 中无内容或无空格作为分隔点,会调用 read 方法往字符串缓冲区 cb 填充内容,现在字符串缓冲区内容为:随意内容 随意内容2 随意内容3

再次调用 getCompleteTokenInBuffer 方法,返回 随意内容

如果调用 read 方法时返回了 -1(规定读到末尾返回 -1),cb 不再填充内容,getCompleteTokenInBuffer 会以空格为分隔点读取 cb 中的内容并返回(如果没有空格,直接读取剩余的所有内容),直至无内容可以读取;

这时再调用 next 方法就会抛出 NoSuchElementException 没有更多的元素异常,可以使用 scanner.hasNext 方法判断是否还有内容可以读取;

如果 cb 一直在填充内容,直到 char 数组容量超出 1024 后,报 BufferOverflowException 缓冲区溢出异常。

 public class TestScanner {     public static void main(String[] args) {         Scanner scanner = new Scanner(new MyReadable());         System.out.println(scanner.next());// 随意内容         System.out.println(scanner.next());// 随意内容2         System.out.println(scanner.next());// 随意内容3随意内容     } } class MyReadable implements Readable {     @Override     public int read(CharBuffer cb) throws IOException {         StringBuilder builder = new StringBuilder("随意内容");         builder.append(" ");         builder.append("随意内容2");         builder.append(" ");         builder.append("随意内容3");          cb.append(builder);         return builder.length();// 没有返回 -1,cb 无限填充内容     } }

System.in 的实际类型为 java.io.BufferedInputStream,可以使用 InputStreamReader 转换成字符流,将输入存入 char 数组。

 InputStreamReader reader = new InputStreamReader(System.in); char[] chars = new char[1024]; int length = reader.read(chars, 0, 1024); System.out.println(new String(chars, 0, length));

没想到啊,handle 是随机生成的唯一句柄

 /**  * 调用 read 方法等待键盘输入,将结果存入 bytes 数组中  */ public static void main(String[] args) throws Exception {     FileDescriptor fd = new FileDescriptor();     Field handle = FileDescriptor.class.getDeclaredField("handle");     handle.setAccessible(true);     handle.set(fd, getHandle());      FileInputStream inputStream = new FileInputStream(fd);     byte[] bytes = new byte[1024];     System.out.print("请输入:");     int length = inputStream.read(bytes);     String result = new String(bytes, 0, length);     System.out.println(result); }  /*  * 获取 obj 的某个字段值,从 obj 的实际类型开始找,找不到就往上找  * 一直到 Object 还没有,抛出异常  */ private static <T> Object getFieldValue(T obj, String fieldName) throws NoSuchFieldException, IllegalAccessException {     Class<?> currentClass = obj.getClass();     while (currentClass != null) {         try {             Field field = currentClass.getDeclaredField(fieldName);             field.setAccessible(true);             return field.get(obj);         } catch (NoSuchFieldException e) {             currentClass = currentClass.getSuperclass();         }     }     throw new NoSuchFieldException(fieldName); }  private static <T> Object getCurrentClassField(T obj, String fieldName) throws IllegalAccessException, NoSuchFieldException {     Field field = obj.getClass().getDeclaredField(fieldName);     field.setAccessible(true);     return field.get(obj); } private static <T> T cast(Object o, Class<T> toClass) {     if (o == null) {         return null;     }     if (toClass.isInstance(o)) {         return toClass.cast(o);     }     throw new ClassCastException(o.getClass() + " cannot be cast to " + toClass); } private static long getHandle() {     try {         // 在 BufferedInputStream 的父类 FilterInputStream 中找到 in 字段         FileInputStream fileInputStream = (FileInputStream) getFieldValue(System.in, "in");         FileDescriptor fd = fileInputStream.getFD();         return (long) getFieldValue(fd, "handle");     } catch (IOException | NoSuchFieldException | IllegalAccessException e) {         throw new RuntimeException(e.getMessage(), e);     } }
6.1.2 普通输出

输出与打印是一个意思,就是使用标准输出流 System.out 在控制台上显示一些文本信息。

System.out.println("向控制台输出一些内容");

println 是 print line,即打印并换行:如果接着打印,内容会在下一行显示;如果想下次打印时,文本在同一行,去掉 ln。

6.1.3 格式化输出

就是把数据按指定格式输出,使用 printf 配合占位符 %,先把地方占着,再接收数据填充上去;

由于没有 ln,需要使用转义字符 \n 手动换行,%d 是给整数占位置,%s 是给字符串占位置。占位后,需要传入值,从左至右,顺序不可颠倒,数据类型必须要对应上。

下面是常用的占位符:

占位符

类型

%d

十进制整数

%x

十六进制整数

%o

八进制整数

%f

浮点数

%e

以科学计数法表示的浮点数

%s

字符串

%c

字符

%b

布尔类型

 String ln = "\n"; System.out.println("班级人员详情:"); String str = "序号:%d,姓名:%s" + ln;          System.out.printf(str, 101, "张三"); System.out.printf(str, 102, "猛男"); System.out.printf(str, 103, "武丑");  System.out.println();  double num = 3.14256; double num2 = 100123450.0; int num3 = 15; System.out.println("数字测试:"); System.out.printf("这是小数:%f" + ln, num); System.out.printf("%f 保留 2 位小数:%.2f" + ln, num, num); System.out.printf("%f 的科学计数法显示:%e" + ln, num2, num2); System.out.printf("%d 对应的十六进制:%x" + ln, num3, num3);

printf 方法底层调用 format 方法实现,所以使用 System.out.format()效果也一样。

6.1.4 输出不同颜色的文字

我一般使用两种颜色打印内容,已足够用了。

 System.out.println("正常内容");// 白色 System.err.println("警告内容");// 红色

也许你不满足这两种颜色,可以输出以下字符串修改字体样式:

"\33[?m"

问号取值如下:(多个 ? 使用 ; 分隔)

 0:原本样式 1:粗体 3:斜体 4:下划线 7:背景颜色与字体颜色互换 9:中划线 21:粗下划线 51、52:方框 30 ~ 37:字体颜色分别为黑色、红色、绿色、黄色、蓝色、紫色、蓝绿色、灰色 40 ~ 47:背景颜色分别为黑色、红色、绿色、黄色、蓝色、紫色、蓝绿色、灰色 90 ~ 97:字体颜色,同 30 ~ 37,但更深

大致分为三类:

fontColor:字体颜色,在 30 ~ 37 范围内,默认白色

background:背景颜色,在 40 ~ 47 范围内,默认黑色

fontStyle:字体样式:1、3、4、9

假如我现在想要输出带中划线的红色粗斜体,选用 9、31、1、3 这 4 种:(顺序不分先后)

System.out.print("\33[9;31;1;3m");System.out.println("指定样式的字体");System.out.println("指定样式的字体2");

想要恢复为原本样式,输出如下字符串:

System.out.print("\33[0m");System.out.println("原本样式");

可以配合占位符使用:

// 格式化输出字符串public static void printf(String str, int fontColor, int background, int fontStyle) {    // 前半部分使用占位符,指定输出字体的样式,后半部分 \33[0m 还原样式,\n 换行    System.out.printf("\33[%d;%d;%dm%s\33[0m\n", fontColor, background, fontStyle, str);}// 返回格式化的字符串public static String getColorString(String str, int fontColor, int background, int fontStyle) {    return String.format("\33[%d;%d;%dm%s\33[0m", fontColor, background, fontStyle, str);}// 输出的字符串为蓝色public static void printlnBlueFont(String str) {    System.out.println(getColorString(str, 34, 2, 2));}// 输出的字符串为紫色public static void printlnPurpleFont(String str) {    printf(str, 35, 2, 2);}
public static void main(String[] args) {    printlnBlueFont("Hello World!");    printlnPurpleFont("Hello World!");    	// 输出蓝色背景、带下划线的红色字体    printf("Hello World!", 31, 44, 4);}
6.2 分支控制语句

内容导视:

if elseswitch case

分支控制语句也称选择语句。

程序一般自上而下,逐行执行,但是有时也需要特殊操作;比如根据条件选择性地执行某段代码、循环执行某段代码...

6.2.1 if else

if else 语句最多只会执行一条分支,类似走路遇见岔路,只能选一条通过。先从最简单的 if 讲起。

单条分支

语法:

if (布尔类型的值) {    java 语句...}

当布尔类型的值为 true 时,才会执行 {} 中的 java 语句,如下:

int age1 = 11;int age2 = 8;if (age1 > age2) {    System.out.println("我比你大");// 此句话会输出}

当 {} 中只有一条语句时,可以省略 {};但是最好不要那么做,以免别人误解。

if (age1 > age2) System.out.println("我比你大");

if else

语法:

if (布尔类型的值) {    分支一...} else {    分支二...}

布尔类型的值为 true,执行第一条分支;为 false,执行第二条分支。

char sex = '1';if (sex == '0') {    System.out.println("输出女");} else {    System.out.println("输出男");// 此句会输出}

多条分支

语法:

if (值1) {    分支一...} else if (值2) {    分支二...} else if (值3) {    分支三...} ...

从上至下,只执行第一个值为 true 的分支;else if 可以无限追加。

double scope = 100.0;if (scope < 60) {    System.out.println("你的成绩不及格");} else if (scope < 80) {    System.out.println("你的成绩一般");} else if (scope < 90) {    System.out.println("你的成绩良好");} else if (scope < 100) {    System.out.println("你的成绩优秀");}

上面的分支都不会执行,因为从上至下,没有布尔表达式为 true 的。

int age = 20;if (age < 18) {    System.out.println("未成年人");} else if (age < 35) {    System.out.println("青年人"); // 此句将会输出} else if (age < 50) {    System.out.println("中年人");}

执行第二条分支。

if else if ... else

语法:

if (值1) {    分支一...} else if (值2) {    分支二...} else if (值3) {    分支三...} ...} else {    最后的分支}    

当所有分支括号里的值都为 false 时,执行最后的分支。

int age = 888;if (age < 18) {    System.out.println("未成年人");} else if (age < 35) {    System.out.println("青年人"); // 此句将会输出} else if (age < 50) {    System.out.println("中年人");} else if (age < 200) {    System.out.println("老年人");} else {    System.out.println("妖怪吧!");// 由于上面分支都不满足,执行此条分支}

嵌套分支

if 语句中有 if 语句。

double scope = 120;if (scope >= 0 && scope <= 100) {    // 语句块 1    if (scope < 60) {   		System.out.println("你的成绩不及格");	} else if (scope < 80) {	    System.out.println("你的成绩一般");	} else if (scope < 90) {   		System.out.println("你的成绩良好");	} else {    	System.out.println("你的成绩优秀");	}    } else {    // 语句块 2    System.out.println("这是人能考出的成绩?");}/*	只有分数在 [0 ~ 100] 之间才会执行语句块 1,否则执行语句块 2*/

嵌套最好不要超过三层,否则人容易迷惑,可读性太差。(可以使用 if else)

if else 不是新的关键字,而是嵌套的简单写法,因为当 if 或 else 中只包含一条 java 语句时,大括号可以省略。(建议不要省略)

if (true)    System.out.println("好");else    System.out.println("差");

例:

int scope = 50;if (scope < 60) {    System.out.println("差");} else if (scope < 80) {    System.out.println("良");} else if (scope <= 100) {    System.out.println("优");}

把被省略的大括号加上:

int scope = 50;if (scope < 60) {    System.out.println("差");} else {    if (scope < 80) {        System.out.println("良");    } else {        if (scope <= 100) {            System.out.println("优");        }    }}
6.2.2 switch case

语法:

switch (值) {	case 字面量1:		语句块1;		break;			case 字面量2:    	语句块2;    	break;    	    case 字面量3:    	语句块3;    	break;    ...    default:    	语句块4;}

从上至下,执行字面量等于 switch 括号中的值的 case 分支语句,遇见 break 跳转至 switch 主体的末尾,然后结束 switch 语句。

default 如同 else 一样,可以不写;当没有一个匹配上时,就执行此分支的语句。

char key = 's';switch (key) {    case 'w' :        System.out.println("上");        break;    case 's' :        System.out.println("下");// 此条将会被输出        break;       case 'a' :        System.out.println("左");        break;      case 'd' :        System.out.println("右");        break;      default:        System.out.println("其它");}

注意

case 后的字面量对应的数据类型必须与 switch 括号中的值的类型一致,或者可以自动转成此类型。case 后的字面量值不能重复。switch 括号中的值的数据类型只能是 int、String、Enum。(能够自动转换为这三种类型的也算)case 后的值不能是变量,只能是字面量与常量。

JDK7 之前只能是 int。

case 穿透现象

当执行某条 case 分支的语句时,如果没有 break 语句结尾,直接顺序执行之下的所有 case、default 分支的语句;只有执行了 break 语句,才会退出 switch 语句。

看清楚了,我把每条分支的 break 都略去了。

String weather = "sunny";switch (weather) {    case "cloudy" :        System.out.println("阴天");    case "sunny" :        System.out.println("晴天");    case "rain" :        System.out.println("雨天");    default:        System.out.println("其它天气");}

当输出 “晴天” 时,由于没有遇到 break 语句,继续执行之下语句,输出 “雨天”、“其它天气”。

打个比方吧:

在一个神奇的小区,房子一排排却单向连通,一旦进入其中一家,便可以由内部通道去往下一家。有的住户觉得很不安全,偷偷做了防范措施。

一个小偷捡到了一把锁,尝试着用它开启一户户门,从巷头走到巷尾。诶,有一扇门开了,进去拿了东西,但是主人安了警报铃,小偷马上 GG 了。另一个小偷也来了,也打开扇门,恰好主人家忽视了防护,小偷偷完这家后,直接顺着通道前往下一家,居然都没防范措施,直接全部偷完。

case 合并

如果多个 case 分支执行的是相同的语句,可以将其合并:

char sex = '男';switch (sex) {    case '0' : case '女' :        System.out.println("我有四个蛋");        break;    case '1' : case '男' :        System.out.println("咖喱?什么咖喱?");        System.out.println("快还给我!这是我的!");        break;    default:        System.out.println("只想守护你");}

当 sex 等于 '0' 或 '女' 时,执行第一条分支;sex 等于 '1' 或 '男' 执行第二条分支;都不满足执行默认分支。

这不是新语法,只是 case '0' 分支中没有语句,包括 break 语句;当 sex = '0' 时,会出现 case 穿透现象,接着执行下个 case 分支中的语句,也就是 case '女',直到遇见 break 退出 switch 语句。

switch (sex) {    case '0' :     case '女' :        System.out.println("我有四个蛋");        break;    case '1' :    case '男' :       ...}

default

同理,default 分支不一定非要在最后一条,也可以与第一条的 case 语句合并,都不匹配时,case 穿透,执行第一条分支。

如下例,都不满足,应执行 default 中的语句,由于 default 中没有 break 语句,接着执行 case 0 分支,输出 0,遇到 break,结束 switch 语句。

switch(3) {    default:    case 0:        System.out.println("0");        break;    case 1:        System.out.println("1");        break;    case 3:        System.out.println("2");        break;  }
6.3 循环控制语句

内容导视:

forwhile

有些时候,我们需要重复执行某些事情...

6.3.1 for

语法:

for (初始化表达式; 布尔值(循环条件); 更新表达式) {    循环体中的语句}

执行顺序:

先执行初始化表达式,如果循环条件为 true,则执行循环体中的语句;

执行完后,执行更新表达式,如果循环条件为 true,则执行循环体中的语句...

直到循环条件为 false,退出 for 语句。

示例:

for (int i = 0; i < 2; i++) {    System.out.println("两指夫人" + i);}

分析:

i --> 0;此时 i 小于 2,为 true,执行循环体中的语句,输出:两指夫人0执行更新表达式 i++i --> 1;此时 i 小于 2,为 true,执行循环体中的语句,输出:两指夫人1执行更新表达式 i++i --> 2;此时 i 小于 2 为 false,退出循环

小技巧:

1)由于定义在 for () 中的变量的作用域仅在 for 循环体内:

for (int i = 0; i < 2; i++) {}System.out.println(i);
Hello.java:8: 错误: 找不到符号System.out.println(i);

为了能够在其它地方能够访问到此变量,可以将其提取出来。

int i = 0;for (; i < 2; i++) {}System.out.println(i);

2)初始化语句与更新表达式可以有多个,使用 , 隔开,但是要求变量的类型相同。

for (int i = 1, j = 2; i < 4 && j < 6; i++, j += 2) {    System.out.println("i:" + i 		+ ",j:" + j);}

分析:

i --> 1,j --> 2i < 4 && j < 6 为 true,执行循环体,输出:i:1,j:2执行更新表达式:i++、j += 2i --> 2,j --> 4i < 4 && j < 6 为 true,执行循环体,输出:i:2,j:4执行更新表达式:i++、j += 2i --> 3,j --> 6i < 4 && j < 6 为 false,结束 for 循环
6.3.2 while

语法:

while (布尔值(循环条件)) {    循环体中的语句}

如果布尔值为 true,执行循环体;执行结束后再判断布尔值...直到布尔值为 false,退出循环。

示例:

int i = 0;while (i < 3) {    System.out.println(i);    i++;}

输出 0、1、2;因为当 i = 3 时,i < 3 为 false,退出循环。

do while

语法:

do {    循环体中的语句} while (布尔值);

先执行循环体,执行结束后判断布尔值,如果为 true,执行循环体,再判断布尔值...直到布尔值为 false,退出循环。

与 while 不同的是,do while 是先执行再判断,所以一定会执行一次。

示例:

int i = 0;do {    System.out.println(i);    i++;} while (i < 3);

输出 0、1、2。

嵌套循环

以 for 循环为例。之前先讲过嵌套,你就理解为套娃就行了,看到阿衰他妈给阿衰做了一笼包子,结果大脸妹打开包子一看,包子里有多个小包子,继续打开,更小的包子...无穷尽也,很影响食欲。嵌套最好不要超过三层,第一怕人发昏,第二是效率低。

for (int i = 0; i < 3; i++) {    for (int j = 0; j < 3; j++) {        System.out.println(j);	}}

分析:

当 i = 0 时,执行循环体输出 0、1、2,当 j = 3 时,不满足条件,结束内层 for 循环当 i = 1 时,执行循环体输出 0、1、2...当 i = 2 时,执行循环体输出 0、1、2...当 i = 3 时,不满足循环条件,退出外层 for 循环

外层的 for 一共循环执行 3 次;每次外层循环时,内层的 for 会循环执行 3 次;也就是内层的循环体中的语句一共执行 3 * 3 = 9 次。

6.4 转向控制语句

内容导视:

breakcontinuereturn

终止或跳过循环...

6.4.1 break

break 代表终止语句块的执行(不再执行),一般用于 switch case、for、while 中。

举例:当 i = 2 时,终止循环。

int i = 0;while (i < 10) {    if (i == 2) {        System.out.println("终止了循环");        break;    }    System.out.println(i);    i++;}

输出 0、1;当 i 等于 2 时,执行 if 语句,输出 “终止了循环”,接着执行 break 终止 for 循环。

当 break 用在嵌套循环中,默认终止最近的循环体。

for (int i = 0; i < 3; i++) {    for (int j = 0; j < 2; j++) {        if (j == 1) {            break;        }        System.out.println(j);    }}

分析:

当 i = 0 时,输出 0当 i = 1 时,输出 0当 i = 2 时,输出 0因为当 j = 1 时,满足了 if 条件,执行了 break,终止了里层的 for 循环。(只是代表里层的循环执行结束,但外层循环还在继续执行)当 i = 3 时,不满足条件,退出外层循环。

也可以自定义标签,终止标签对应的循环。

key1: for (int i = 0; i < 3; i++) {    key2: for (int j = 0; j < 2; j++) {        if (j == 1) {                      break key1;        }        System.out.println(j);    }}

输出 0;当 j = 1 时,执行了 break,终止 key1 对应的 for 语句。

6.4.2 continue

跳过本次循环。(提前结束本次循环,开始下一次循环)

int i = 0;while (i < 6){    i++;    if (i == 3){        continue;    }    System.out.println(i);}

当 i = 3 时,执行了 continue,跳过本次循环,没有执行剩下的代码,直接进入下一次循环。所以输出 1、2、4、5、6。

需要注意的是,此时我把 “i++” 放在了前面;因为 i++ 如果在 continue 后,当 i = 3 时,跳过本次循环,没有执行 i++,下次循环 i 还是 3,一直跳过,无限循环,永远执行不到 i++。

6.4.3 return

当方法没有返回值(void)时,使用 return; 代表结束当前方法的执行。(结束当前方法意味着其它语句不再执行;在 main 方法中使用代表结束程序)

public static void main(String[] args) {    // for    for (int i = 0; i < 6; i++) {        System.out.println(i);        if(i == 4) {            return;// 同一个域中,此语句必须放到结尾处,因为之后的语句执行不到,没有意义        }	}    // 其它语句	System.out.println("代码块");}

输出 0、1、2、3、4 后,当 i = 4 时,执行 if 语句中的 return,结束 main 方法的执行。

如果把 return 换成 break,只结束了 for 循环,接着还会输出 “代码块”。

return 以后讲方法返回值时还会用到,现在只需了解它能够终止方法执行即可。

6.x 总结回顾

switch case 语句注意 break 不可省略,以免出现 case 穿透现象。

for 与 while 循环注意控制循环结束条件,防止循环条件一直为 true,避免无限循环。

6.y 课后习题

6.1 打印 [n,m] 之间的所有是 x 倍数的整数,统计个数及总和。

6.2 输出 1 + (n - 1)= n、2 + (n - 2)= n、...、50 + (n - 50)= n。

6.3 打印九九乘法口诀表。

6.4 打印一个 n 层的空心金字塔。例:当 n = 5 时,输出如下:

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

6.5 找出 3 位数的水仙花数,水仙花数是各位数的三次方之和等于此数,比如 153 = 13 + 53 + 33 = 153。

6.6 计算 1 - 1/2 + 1/3 - 1/4 + ... - 1/100。

6.7 计算 1 + (1 + 2)+ (1 + 2 + 3)+ ... + (1 + 2 + 3 + 4 + ... + 100)。

6.z 习题答案

6.1 打印 [n,m] 之间的所有是 x 倍数的整数,统计个数及总和。

先考虑输出 [1,50] 之间所有是 5 的倍数:

// (1)输出 1 ~ 50for (int i = 1; i <= 50; i++) {    System.out.println(i);}
// (2)只有当 i 是 5 的倍数时,才输出for (int i = 1; i <= 50; i++) {    if (i % 5 == 0) {    	System.out.println(i);    }}
// (3)定义变量保存统计个数、和int count = 0;int sum = 0;for (int i = 1; i <= 50; i++) {    if (i % 5 == 0) {        count++;    	sum += i;    }}System.out.println("总和:" + sum);System.out.println("是 5 的倍数的数的个数:" + count);
// (4)扩展到一般情况// 这里可以考虑接收键盘输入,得到整数值int n = 1;int m = 50;int x = 5;int count = 0;int sum = 0;for (int i = n; i <= m; i++) {    if (i % x == 0) {        count++;    	sum += i;    }}System.out.println("总和:" + sum);System.out.println("是 " + x + " 的倍数的数的个数:" + count);

6.2 输出 1 + (n - 1)= n、2 + (n - 2)= n、...、50 + (n - 50)= n。

观察变的部分,1 ~ 50,将其提取出来,定义为 i:

for (int i = 1; i <= 50; i++) {    System.out.println(i + " + (n - " + i + ") = n");}

6.3 打印九九乘法口诀表。

效果如图:

由于我们是按行输出的,所以观察递增的部分:1 ~ 9;也就是乘号右边。

for (int i = 1; i <= 9; i++) {    System.out.println(i);}

观察乘号左边与 i 的关系

当 i = 1 时,输出 1i = 2 时,输出 1、2i = 3 时,输出 1、2、3...i = 8 时,输出 1、2、3、4、5、6、8i = 9 时,输出1、2、3、4、5、6、8、9可以发现输出的开始都是 1,结束都是 i定义一个变量 j,使用 for 循环输出这些值
for (int i = 1; i <= 9; i++) {    System.out.print(i + "\t");    for (int j = 1; j <= i; j++) {        System.out.print(j + " ");    }    System.out.println();}

开始组合 “j * i = 某值” 字符串:

for (int i = 1; i <= 9; i++) {     for (int j = 1; j <= i; j++) {        System.out.print(j + "x" + i 			+ "=" + (i * j) + "\t");    }    System.out.println();}

注意同行显示的乘法口诀,别用 ln 换行了;应该输出完这行所有的乘法口诀后,再换行。

6.4 打印一个 n 层的空心金字塔。例:当 n = 5 时,输出如下:

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

简化 1:打印实心金字塔

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

简化 2:将星号前面空格去掉

*************************第 2 层是 1+2 = 2*2 - 1第 3 层是 1+2+2 = 2*3 - 1第 4 层是 1+2+2+2 = 2*4 - 1

通过观察,发现每层都比上层多 2 个星号,通过归纳得出第 i 层为 2 * i - 1 个星号。

先打印 5 层。i 控制层数 1 ~ 5 层;j 控制每层的星号数,一共输出 2 * i - 1 个星号。

for (int i = 1; i <= 5; i++) {    for (int j = 1; j <= 2 * i - 1; j++) {        System.out.print("*");    }    System.out.println();}

接下来观察简化 1:

第 1 行前面有 4 个空格第 2 行前面有 3 个空格第 3 行前面有 2 个空格第 4 行前面有 1 个空格第 5 行前面有 0 个空格所以当第 i 行前面应该打印 5 - i 个空格后再打印 *
for (int i = 1; i <= 5; i++) {    for (int z = 1; z <= 5 - i; z++) {        System.out.print(" ");    }    for (int j = 1; j <= 2 * i - 1; j++) {        System.out.print("*");    }    System.out.println();}

接下来观察最初的空心版本,除了最后一层,其它层除了开始的和结束的星号,都输出空格:

for (int i = 1; i <= 5; i++) {    for (int z = 1; z <= 5 - i; z++) {        System.out.print(" ");    }    for (int j = 1; j <= 2 * i - 1; j++) {        // 不是最后一层,除了开始与结束输出星号,其它都输出空格        if (i != 5) {            if (j == 1 || j == 2 * i - 1) {                System.out.print("*");               } else {                System.out.print(" ");               }        } else {            System.out.print("*");        }    }    System.out.println();}

最后将 5 改为 n:

int n = 10;for (int i = 1; i <= n; i++) {    for (int z = 1; z <= n - i; z++) {        System.out.print(" ");    }    for (int j = 1; j <= 2 * i - 1; j++) {        if (i != n) {            if (j == 1 || j == 2 * i - 1) {                System.out.print("*");               } else {                System.out.print(" ");               }        } else {            System.out.print("*");        }    }    System.out.println();}

6.5 找出 3 位数的水仙花数,水仙花数是各位数的三次方之和等于此数,比如 153 = 13 + 53 + 33 = 153。

首先需要得到各位上的数:

设一个三位数的整数 i,把百位、十位、个位上的数得到百位 = i / 100十位 = i % 100 / 10或十位 = i / 10 % 10个位 = i % 10

那么从 100 ~ 999 范围内查找,当满足水仙花就输出:

for (int i = 100; i < 1000; i++) {    int h = i / 100;    int t = i % 100 /10;    int u = i % 10;    // 可用 Math 的 pow 方法求幂    if (i == h * h * h + t * t * t + u * u * u) {        System.out.println(i);    }}

扩充内容:

得到四位数上的各位数,以 1234 为例

千 1234 / 1000    百 1234 % 1000 / 100 或 1234 / 100 % 10十 1234 % 100 / 10 或 1234 / 10 % 10个 1234 % 10

6.6 计算 1 - 1/2 + 1/3 - 1/4 + ... - 1/100。

观察规律:

分子都为 1,分母以 1 递增到 100;设为 i,当 i 为偶数时,符号为负。

double sum = 0;for (int i = 1; i <= 100; i++) {    if (i % 2 == 0) {        sum += -1.0 / i;    } else {        sum += 1.0 / i;    }    /*    double num = i % 2 == 0 ? -1.0 / i : 1.0 / i;    sum += num;    */}System.out.println(sum);// 0.688172179310195

分子的 1 必须写成小数,否则除了第一项其它式子的结果都为 0;sum 必须为 double 类型,如果为 int 类型,+= 会被强转为整数,恰巧结果小于 1,统统转成 0。

6.7 计算 1 + (1 + 2)+ (1 + 2 + 3)+ ... + (1 + 2 + 3 + 4 + ... + 100)。

方法 1:

一共有 100 个式子相加第 1 个式子是 1第 2 个式子是 1+2第 3 个式子是 1+2+3得出规律,当 i > 1 时第 i 个式子是从 1 加到 i,想办法把 1 到 i 这几个数弄到手,累加定义 i 控制式子的个数,从 1 到 100定义 j 控制每个式子,从 1 加到 i
int sum = 0;for (int i = 1; i <= 100; i++) {    for (int j = 1; j <= i; j++) {        sum += j;    }}System.out.println(sum);// 171700

方法 2:

 第 1 个式子是 1 = 1 第 2 个式子是 1+2 = 3 第 3 个式子是 1+2+3 = 6  得出规律,当 i > 1 时 第 i 个式子是第 i-1 个式子的结果 + i  i 从 1 到 100 考虑使用 formula 记录第 1 个式子的和,然后不停地累加 i。 第一次循环,formula = 1 第二次循环,formula + i = 1 + 2 = 3 第三次循环,formula + i = 3 + 3 = 6 ... 每个式子的和得到了,再定义 sum 变量将这些式子的和累加,即 sum += formula 同时为了和谐,修正 formula = 0;第一次循环 formula + i = 0 + 1 = 1
 int formula = 0; int sum = 0; for (int i = 1; i <= 100; i++) {     formula += i;     sum += formula; } System.out.println(sum);

方法 3:

 观察式子 发现 1 出现了 100 次,2 出现了 98 次...100 出现了 1 次 所以总和为 1 * 100 + 2 * 99 + ... + 100 * 1
 int sum = 0; for (int i = 1; i <= 100; i++) {     sum += i * (101 - i); } System.out.println(sum);

扩展为一般情况:

 int n = 100; int sum = 0; for (int i = 1; i <= n; i++) {     sum += i * (n + 1 - i); } System.out.println(sum);

标签: #java 输入输出能变颜色吗