首页 > 解决方案 > 仅使用星号和递归绘制 X 形状

问题描述

考虑这段代码。

public static void patternMaker(int start, int max, int direction) {
    if (start == 0) {
        return;
    }
    for (int i = 0; i < start; i++) {
        System.out.print("*");
    }
    System.out.println();
    if (start == max) {
        direction = -1;
    }

patternMaker(start +direction, max, direction);

输出看起来像这样。

在此处输入图像描述

我需要它看起来像这样

在此处输入图像描述

所以我基本上需要同样的东西,但从另一边,我需要向右移动一个空间和每一个新行。我不知道如何产生它,我尝试复制方向以获得另一部分X 但没有成功。也不确定如何将每行向右移动一个空格,我假设 id 需要在每次迭代时调整方向,但错过了一个好主意。谢谢!

标签: javarecursion

解决方案


当需要使用递归时,这里是基于您提供的代码示例的解决方案:

我将打印部分外包给了一个单独的方法。

public static void patternMaker(int max) {
  patternMaker(1, max, 1);
}

public static void patternMaker(int numOfStars, int max, int direction) {
  if (numOfStars == 0) {
    return;
  }

  if (numOfStars == max) {
    //print the maximum number of stars also before the middle
    printPatternLine(numOfStars, max, false); 

    //print middle part twice
    printPatternLine(numOfStars, max, true); 
    printPatternLine(numOfStars, max, true); 

    direction = -1;
  }
  printPatternLine(numOfStars, max, false);

  patternMaker(numOfStars + direction, max, direction);
}

private static void printPatternLine(int numOfStars, int max, boolean middle) {
  int spacesBefore;
  int spacesBetween;

  if(middle) {
    spacesBefore = numOfStars;
    spacesBetween = 0;
  } else {
    spacesBefore = numOfStars -1;
    if(numOfStars == max) {
      spacesBetween = 2;
    } else {
      spacesBetween = (max - numOfStars) * 4 + 2;
    }
  }

  //print the spaces before the stars
  for (int i = 0; i < spacesBefore; i++) {
    System.out.print(" ");
  }
  //print first part of stars
  for (int i = 0; i < numOfStars; i++) {
    System.out.print("*");
  }
  //print spaces between the stars
  for (int i = 0; i < spacesBetween; i++) {
    System.out.print(" ");
  }
  //print second part of stars
  for (int i = 0; i < numOfStars; i++) {
    System.out.print("*");
  }
  //linebreak
  System.out.println();
}

在 X-drawing 的中间部分,printPatternLine被多次调用,为了打印这个数量的星星,对于这个patternMaker方法的调用,总共打印了四次。

该方法的简短说明printPatternLine

  • 打印星星之前的空间和星星之间的空间是之前计算的
  • 中间部分的情况应该是不言自明的(中间没有空格,前面的空格等于星星的数量)
  • 对于非中间部分
    • 星星之前的空格数与该行的第一个星星的位置有关(对于 1 * 不打印空格,对于 2 个星星,打印 1 个空格,...)
    • 星星之间的空格数为 2,对于在中间上方的那条线(每边多 1 个空格,每边多 1 个星星)。对于离中间远一行的每一行,中间的空格增加 4。

如果您patternMaker通过调用仅使用一个参数执行该方法

patternMaker(3);

它将打印此模式:

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

如果您需要星之间的空格,请将 for 循环前面的空格数乘以 2,然后在星形输出中添加一个空格,如下所示:

private static void printPatternLine(int numOfStars, int max, boolean middle) {
  //...

  spacesBefore *= 2;
  spacesBetween *= 2;

  //...

  for (int i = 0; i < numOfStars; i++) {
    System.out.print("* ");
  }

  //...

  for (int i = 0; i < numOfStars; i++) {

    System.out.print("* ");
  }

  //...
}

这是patternMaker(3);带有空格的示例输出:

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

编辑:改编,如果中间部分应该包含比它前后的行更多的星星,很容易实现。


推荐阅读