Java 用for循环打印菱形和空心菱形

打印菱形

最近跟着学校的老师再重学Java,又遇到一个十分熟悉的题目:要求在控制台打印出如图所示的菱形。但是都大四了,至少要能实现根据用户的输入,来确定打印菱形的行数吧?

 看到题目的第一眼就知道是用for循环来做,关键在于循环停止的条件。依稀记得以前做这题时是分为上下两部分来分别打印,同时用for循环打印每一行的字符时,嵌套两个循环来打印制表符(\t)和星型字符(*)。

有了初步的思路后,就要靠找规律来得出循环条件。

首先是打印菱形的上半部分。因为菱形是奇数行,所以暂且把第三行归为上半部分。菱形一共有5行,上半部分的行数3就可以等于(5+1)/2;依此类推,若有x行,则为(x+1)/2。为方便计算,若用户输入的行数为偶数需要进行转换。

1.进行奇偶判断

	/**
	 * 奇偶判断
	 * 
	 * @param x
	 * @return false为偶,true为奇
	 */
	public static boolean determineOddOrEven(int x) {
		boolean flag;
		if (x % 2 == 0) {
			flag = false;
		} else {
			flag = true;
		}
		return flag;
	}

2.计算菱形上半部分的行数

	int i = 0; // 菱形上半部分的行数
	/*
	 * 调用determineOddOrEven(x)方法,判断输入的值为奇还是偶,
         * 由于菱形总行数应为奇数,故打印上半部分时为:(行数+1)/2
	 */
	if (!determineOddOrEven(x)) {
		i = x / 2;
		System.out.println("你输入的数为偶数,程序已将其转换为小1的奇数");
	} else {
		i = (x + 1) / 2;
	}

接着是打印用来空位的制表符,从上半部分的图形可以看出,第一行空了2位,第二行空了1位,第三行空了0位,不难得出空位数是3-line(line为该行的行数,从1开始计数);依此类推,若菱形有x行,那么上半部分每行的空位数应为(x+1)/2-line,即i-line。

下面就要打印每行的星型字符(*),星型字符的个数为1、3、5,易得其个数为首项是1,公差是2的等差数列,即*的个数为(1+2*(line-1) => 2*line-1。

	/*
	 * 逐行打印菱形上半部分,以5行的菱形为例 上半部分有3行,即i=(总行数+1)/2
	 */
	for (int line = 1; line <= i; line++) {
		// 打印制表符,以上半部分为例,可见第一行有2个空位(3-1),
		// 第二行有1个(3-2),第三行有0个(3-3),
                // 可得上半部分每行的空位数为(i-line),line为该行的行数
		for (int n = 0; n < i - line; n++) {
			System.out.print("\t");
		}
		// 打印*,不难看出每行*的个数为为1、3、5,易得
		// 每行*的个数为((2*line)-1),line为该行的行数
		for (int n = 0; n < 2 * line - 1; n++) { // 打印字符
			System.out.print("*\t");
		}
		System.out.println();
	}

打印完菱形的上半部分还有下半部分需要打印,首先要算的还是下半部分的行数。因为共有x行,上半部分已经打印了i行,所以下半部分为(x-i),又因为i=(x+1)/2 => x=2*i-1,所以这里的(x-i)与(i-1)等价。

接着还是要打印制表符,可以看出下半部分的第1行有1个空位,第2行有2个,故其个数可表现为首项为1,公差为1,项数为其所在行行数的等差数列,即1+1*(n-1) => n。

下面打印星型字符*,易得其个数为首项为(x-2),公差为-2的等差数列,即(x-2)+(-2)*(n-1) => x-2n。

	// 逐行打印菱形下半部分,下半部分共有i-1行
	for (int n = 1; n <= i - 1; n++) {
		// 打印制表符
		// 与上半部分相反,下半部分每行的空位成递增
		// 且与该行在下半部分的行数相等
		for (int k = 0; k < n; k++) {
			System.out.print("\t");
		}
		// 打印*,下半部分的*个数,仍为奇数,却成递减
		// 该处的2*(i-n)-1与x-2*n等价
		// x-2*n即菱形左右两侧各少了m个,m又与从下半部分看的行数n相等,故还剩x-2*n个
		// x-2*n亦可视为首项为(x-2),公差为-2的等差数列
		for (int k = 0; k < 2 * (i - n) - 1; k++) {
			System.out.print("*\t"); // 打印字符
		}
		System.out.println();
	}

至此,整个菱形都打印出来了,下面贴上完整的代码。

package day01;

import java.util.Scanner;

public class Work03 {
	/**
	 * 奇偶判断
	 * 
	 * @param x
	 * @return false为偶,true为奇
	 */
	public static boolean determineOddOrEven(int x) {
		boolean flag;
		if (x % 2 == 0) {
			flag = false;
		} else {
			flag = true;
		}
		return flag;
	}

	/**
	 * 打印菱形
	 */
	public static void printRhombus() {

		System.out.println("请输入你要打印菱形的行数(请输入奇数):");

		Scanner scanner = new Scanner(System.in);// 实例化Scanner,用于接收键盘输入
		int x = scanner.nextInt(); // 获取输入的行数值
		
		int i = 0; // 菱形上半部分的行数
		/*
		 * 调用determineOddOrEven(x)方法,判断输入的值为奇还是偶, 由于菱形总行数应为奇数,故打印上半部分时为:(行数+1)/2
		 */
		if (!determineOddOrEven(x)) {
			i = x / 2;
			System.out.println("你输入的数为偶数,程序已将其转换为小1的奇数");
		} else {
			i = (x + 1) / 2;
		}

		/*
		 * 逐行打印菱形上半部分,以5行的菱形为例 上半部分有3行,即i=(总行数+1)/2
		 */
		for (int line = 1; line <= i; line++) {
			// 打印制表符,以上半部分为例,可见第一行有2个空位(3-1),
			// 第二行有1个(3-2),第三行有0个(3-3),可得上半部分每行的空位数为(i-line),line为该行的行数
			for (int n = 0; n < i - line; n++) {
				System.out.print("\t");
			}
			// 打印*,不难看出每行*的个数为为1、3、5,也就是奇数的等差数列,易得
			// 每行*的个数为((2*line)-1),line为该行的行数
			for (int n = 0; n < 2 * line - 1; n++) { // 打印字符
				System.out.print("*\t");
			}
			System.out.println();
		}

		// 逐行打印菱形下半部分,下半部分共有i-1行
		for (int n = 1; n <= i - 1; n++) {
			// 打印制表符
			// 与上半部分相反,下半部分每行的空位成递增
			// 且与该行在下半部分的行数相等
			for (int k = 0; k < n; k++) {
				System.out.print("\t");
			}
			// 打印*,下半部分的*个数,仍为奇数,却成递减
			// 该处的2*(i-n)-1与x-2*n等价
			// x-2*n即菱形左右两侧各少了m个,m又与从下半部分看的行数n相等,故还剩x-2*n个
			// x-2*n亦可视为首项为(x-2),公差为-2
			for (int k = 0; k < 2 * (i - n) - 1; k++) {
				System.out.print("*\t"); // 打印字符
			}
			System.out.println();
		}
		scanner.close();
	}

	public static void main(String[] args) {
		printRhombus();
	}
}

运行结果:

打印空心菱形

该题目的后续是打印空心菱形,其实实心的已经打印出来了,空心的也就不难了。对于空心菱形来说,其菱形外围的空位与实心的并没有区别,需要修改的只有打印星型字符的部分。其之所以是空心的,是因为每行只有首位两个*是打印出来的,故只要在打印*时添加一个判断条件,只有他在每行的第一个或者最后一个的时候才打印*,否则就用制表符来占位。

以菱形上半部分为例:

	for (int line = 1; line <= i; line++) { 		// 逐行打印菱形上半部分
		for (int n = 0; n < i - line; n++) { 		// 打印制表符
			System.out.print("\t");
		}
		for (int n = 0; n < 2 * line - 1; n++) { 	// 打印字符
			if((n==0)||(n==2*line-2)) {
				System.out.print("*\t");
			}else {
				System.out.print("\t");
			}
		}
		System.out.println();
	}

下面贴上打印空心菱形的完整代码:

package day04;

import java.util.Scanner;

public class Work02 {

//	输入菱形的行数,如果行数非法则重新输入。根据行数打印一个空心菱形

	public static int determineOddOrEven(int x) { 		// 奇偶判断,0为偶,1为奇
		int m;
		if (x % 2 == 0) {
			m = 0;
		} else {
			m = 1;
		}
		return m;
	}

	public static void printRhombus() {

		System.out.println("请输入你要打印菱形的行数(请输入奇数):");

		Scanner scanner = new Scanner(System.in);
		int x = scanner.nextInt();
		int i = 0; 							

		switch (determineOddOrEven(x)) {
		case (0):
			i = x / 2;
			System.out.println("你输入的数为偶数,程序已将其转换为小1的奇数");
			break;
		case (1):
			i = (x + 1) / 2;
			break;
		}

		for (int line = 1; line <= i; line++) { 	// 逐行打印菱形上半部分
			for (int n = 0; n < i - line; n++) { 	// 打印制表符
				System.out.print("\t");
			}
			for (int n = 0; n < 2 * line - 1; n++) {    // 打印字符
				if((n==0)||(n==2*line-2)) {
					System.out.print("*\t");
				}else {
					System.out.print("\t");
				}
			}
			System.out.println();
		}

		for (int n = 1; n <= i - 1; n++) { 		// 逐行打印菱形下半部分
			for (int k = 0; k < n; k++) { 		// 打印制表符
				System.out.print("\t");
			}
			for (int k = 0; k < 2 * (i - n) - 1; k++) {
				if((k==0)||(k==2*(i-n)-2)) {
					System.out.print("*\t"); 				// 打印字符
				}else {
					System.out.print("\t");
				}
			}
			System.out.println();
		}
	}

	public static void main(String[] args) {
		printRhombus();
	}
}

运行结果:

 

发布了4 篇原创文章 · 获赞 0 · 访问量 3216
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章