当前位置:首页 > 后端开发 > 正文

java怎么打印沙漏

va打印沙漏需先确定有效符号数,用循环控制每行空格与符号数量,上半部递减、下半部递增实现对称结构

Java中打印沙漏形状是一个经典的编程练习题,它结合了数学计算、循环结构和字符串操作等多种技能,下面将详细介绍如何实现这一功能,包括算法思路、具体步骤以及完整的代码示例。

核心概念解析

所谓“沙漏形状”,是指满足以下条件的图形:

  1. 每行输出奇数个符号
  2. 各行符号中心对齐
  3. 相邻两行符号数差2
  4. 符号数量先从大到小顺序递减到1,再从小到大顺序递增
  5. 首尾行的符号数相等

当输入为17个星号()时,应形成如下结构:

实现步骤详解

确定最大可用层数n

我们需要找到一个最大的整数n,使得总消耗的符号数不超过给定的N,根据等差数列求和公式,一个完整的沙漏所需的符号总数为4n²−1(上半部分三角区+下半部分倒置三角区),可以通过求解不等式4k²−1≤N来获得最大的k值,实际处理中,可以使用数学函数Math.sqrt((N+1)/4)并向下取整得到初始猜测值,然后逐步验证调整。

计算实际使用的符号总数used

一旦确定了层数n,就可以精确计算出该沙漏实际需要的符号数量:used = 4nn 1,这代表了上下两个等腰三角形叠加后的总字符数。

分层打印逻辑

整个打印过程分为两部分:上半部分(正立的等腰三角形)和下半部分(倒置的等腰三角形),每一行的打印都需要考虑前导空格的数量和当前行的符号个数。

行类型 范围 前导空格数 当前行符号数 说明
上半部分 i从n降到1 n−i 2i−1 随着i减小,宽度逐渐变窄
下半部分 i从2升到n n−i 2i−1 随着i增大,宽度再次扩展

处理边界情况

特别注意中间那一行的特殊处理——它是连接上下两部分的关键节点,此时i=1,对应只有一个中心点,还要确保所有行的居中效果一致,即通过添加适当数量的前导空格实现视觉上的对齐。

Java完整实现代码

以下是符合上述逻辑的Java程序:

import java.util.Scanner;
public class PrintHourglass {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();      // 读取总符号数
        String ch = sc.next();     // 读取要打印的符号
        // 计算最大可能的层数n
        int n = (int) Math.sqrt((N + 1) / 4.0);
        while (4  n  n 1 > N) {
            n--;
        }
        int used = 4  n  n 1; // 实际使用的符号数
        System.out.println("剩余符号数:" + (N used));
        // 打印上半部分(包括中间一行)
        for (int i = n; i >= 1; i--) {
            // 打印前导空格
            for (int j = 0; j < n i; j++) {
                System.out.print(" ");
            }
            // 打印符号
            for (int j = 0; j < 2  i 1; j++) {
                System.out.print(ch);
            }
            System.out.println();
        }
        // 打印下半部分
        for (int i = 2; i <= n; i++) {
            // 打印前导空格
            for (int j = 0; j < n i; j++) {
                System.out.print(" ");
            }
            // 打印符号
            for (int j = 0; j < 2  i 1; j++) {
                System.out.print(ch);
            }
            System.out.println();
        }
    }
}

代码解释

  1. 输入处理:使用Scanner类获取用户输入的两个参数——总符号数N和指定符号ch。
  2. 层数计算:基于平方根函数初步估算层数n,并通过循环确保不会超出可用符号限制。
  3. 用量统计:变量used存储了构成沙漏所需的全部符号数目,便于后续输出剩余量。
  4. 上半部分绘制:外层循环控制行数变化,内层第一个循环负责生成左侧空白区域,第二个循环填充相应数量的目标符号。
  5. 下半部分绘制:类似上半部分的逻辑,但起始值为2以避免重复打印中间行。
  6. 自动换行:每次完成一行后调用System.out.println()实现自动换行。

示例运行结果

若输入为17 ,则输出如下:

java怎么打印沙漏  第1张


 
  
   
    
   
  
 

剩余符号数:0

FAQs

Q1: 如果输入的N不足以构成完整的沙漏怎么办?
A: 程序会自动选择最大的可行层数n,使得4n²−1≤N成立,未被使用的符号会在最后单独显示其数量,若N=10,则只能构建一个小规模的沙漏,并提示剩余若干符号未被使用。

Q2: 能否修改代码以支持不同的字符作为填充材料?
A: 当然可以!只需更改输入阶段的第二个参数即可,当前的实现已经接受任意单个字符作为填充符,如, 等,只需在运行程序时传入相应的字符即可看到效果

0