简体   繁体   English

使用递归打印空心正方形

[英]Printing a hollow square using recursion

I've been searching around for this question, and have been receiving answers by using purely for-loops. 我一直在寻找这个问题,并通过使用纯for循环获得了答案。 The code I have so far is as follows: 到目前为止,我的代码如下:

import java.util.Scanner;

public class HollowSquare {


    public static void main(String args[]) {
        Scanner ma = new Scanner(System.in);
        System.out.print("Enter the number:");
        int max = ma.nextInt();

        for (int i = 1; i <= max; i++) {
            for (int j = 1; j <= max; j++) {

                if ((i == 1) || (i == max)) {
                    System.out.print("*");
                } else {
                    if (j == 1 || j == max) {
                        System.out.print("*");
                    } else {
                        System.out.print(" ");
                    }
                }
            }
            System.out.println();
        }
    }
}

While I understand the concept of recursion, I'm unsure of how to implement it in this area, and at this point, I've been looking at various if statements and using global variables (maybe not the best idea, but I'm relatively new to the concept of recursion). 虽然我了解递归的概念,但不确定如何在此领域实现递归,目前,我一直在研究各种if语句和使用全局变量(也许不是最好的主意,但是我相对于递归的概念而言相对较新)。

I want to be able to understand recursion better than I do now, and this is one of the problems that I currently do not understand in terms of recursion. 我希望能够比现在更好地理解递归,这是我目前在递归方面尚不了解的问题之一。

Thank you to anyone and everyone who is able to help! 谢谢任何能够提供帮助的人!

For the sake of recursion only. 仅为了递归。 I even have one recursive method, repeatMiddleLine , call a different method that is in itself recursive, repeatChar . 我什至有一个递归方法repeatMiddleLine ,调用了另一个本身递归的方法repeatChar

public class HollowSquare {

    private static final char squareChar = '*';
    private static final char holeChar = ' ';

    public static void main(String[] args) {
        try (Scanner ma = new Scanner(System.in)) {
            System.out.print("Enter the number:");
            int max = ma.nextInt();
            repeatChar(squareChar, max);
            System.out.println();
            repeatMiddleLine(max - 2, max);
            repeatChar(squareChar, max);
            System.out.println();
        }
    }

    private static void repeatMiddleLine(int lineCount, int lineLength) {
        if (lineCount > 0) {
            System.out.print(squareChar);
            repeatChar(holeChar, lineLength - 2);
            System.out.println(squareChar);
            repeatMiddleLine(lineCount- 1, lineLength);
        }
    }

    private static void repeatChar(char c, int count) {
        if (count > 0) {
            System.out.print(c);
            repeatChar(c, count - 1);
        }
    }

}

When I enter 4, it prints: 当我输入4时,它会打印:

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

Like you I am not doing any input validation. 像您一样,我没有进行任何输入验证。 The user may type -30 and I don't know what the output will be, maybe a couple of blank lines. 用户可以输入-30,但我不知道输出是什么,也许是几个空行。 Or 20000000, and a stack overflow is likely. 或20000000,可能会出现堆栈溢出。 With input 1 it prints 2 lines each containing an asterisk. 使用输入1时,它将打印2行,每行包含一个星号。 I believe you for loops behave better in this case. 我相信您的循环在这种情况下表现更好。 You can repair it if you want. 如果需要,可以修复它。

The basic idea is to write your recursive method so that it tracks which line you're on for half the number of lines, and: 基本思想是编写递归方法,以便它以一半的行数跟踪您所在的行,并且:

  1. writes the appropriate number of stars; 写出适当数量的星星;
  2. calls itself recursively, decrementing the line count; 递归调用自身,减少行数;
  3. after the recursion writes the appropriate number of stars again (which produces the bottom half of the square). 递归再次写入适当数量的星星(产生正方形的下半部分)。

Step (3) is complicated slightly by checking whether you should skip if you're halfway through and have an odd value for n , in which case you don't want to write the additional line. 步骤(3)通过检查是否中途跳过是否具有n的奇数来略微复杂,在这种情况下,您不想编写其他行。

Here it is, written in Ruby. 这是用Ruby编写的。 I didn't want to just give you the answer, and Ruby is practically pseudocode except you can actually run it. 我不想只是给你答案,而Ruby实际上是伪代码,但实际上可以运行它。

def print_all_stars(n)
  puts '*' * n    # print n asterisks on a line
end

def print_end_stars(n)
  puts '*' + (' ' * (n - 2)) + '*'   # print an asterisk, n-2 spaces, and an asterisk
end

# The following method takes two arguments, but the 2nd arg
# has a default value if not explicitly specified.  This negates
# the need for end users to kick-start things by calling
# print_square(n, n), which would probably confuse people.

def print_square(n, current_level = n)
  # recursive base case, start backing out if we're halfway through the square
  return if current_level <= n / 2

  # step 1.
  if current_level == n
    print_all_stars(n)
  else
    print_end_stars(n)
  end

  # step 2.
  print_square(n, current_level - 1)    # recursive call!

  # Work done after the recursive call happens in reverse order,
  # as we back out of the call stack.  The following will print
  # the bottom half of the square, mirroring the top half except
  # for the case where n is odd.  In that case, we only want this
  # level of the recursion to print one line, not two. 

  # step 3.
  if current_level == n
    print_all_stars(n)
  elsif current_level > (n + 1) / 2    # here's the odd n check
    print_end_stars(n)
  end
end

print_square(3)

# produces:
#
#  ***
#  * *
#  ***

print_square(4)

# produces:
#
#  ****
#  *  *
#  *  *
#  ****

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM