繁体   English   中英

用字符打印金字塔图案

[英]Printing pyramid pattern out of characters

我需要打印金字塔形状的字符数组。 到目前为止我所拥有的是:

char[] chars = {'F', 'E', 'L', 'I', 'Z', ' ', 'A', 'N','I', 'V', 'E', 'R', 'S', 'A', 'R', 'I', 'O'};
    int length = chars.length;


  for (int i = 1; i < length; i += 2) {
  for (int j = 0; j < 9 - i / 2; j++)
    System.out.print(" ");

  for (int j = 0; j < i; j++)
    System.out.print(chars[j]);

  System.out.print("\n");
}
  for (int i = length; i > 0; i -= 2) {
  for (int j = 0; j < 9 - i / 2; j++)
    System.out.print(" ");

  for (int j = 0; j < i; j++)
    System.out.print(chars[j]);

  System.out.print("\n");

并打印出这个:

           F
          FEL
         FELIZ
        FELIZ A
       FELIZ ANI
      FELIZ ANIVE
     FELIZ ANIVERS
    FELIZ ANIVERSAR
   FELIZ ANIVERSARIO
    FELIZ ANIVERSAR
     FELIZ ANIVERS
      FELIZ ANIVE
       FELIZ ANI
        FELIZ A
         FELIZ
          FEL
           F

但我需要它从数组中间的字符开始打印。 最终结果必须是这样的:

                       I
                      NIV
                     ANIVE
                    ANIVER
                   Z ANIVERS
                  IZ ANIVERSA
                 LIZ ANIVERSAR
                ELIZ ANIVERSARI
               FELIZ ANIVERSARIO
                ELIZ ANIVERSARI
                 LIZ ANIVERSAR
                  IZ ANIVERSA
                   Z ANIVERS
                    ANIVER
                     ANIVE
                      NIV
                       I

任何帮助将不胜感激。

您可以执行与以下代码中显示相同的操作。 它将使用较少数量的for循环。 我在代码中添加了内联注释。

    char[] chars = { 'F', 'E', 'L', 'I', 'Z', ' ', 'A', 'N', 'I', 'V', 'E', 'R', 'S', 'A', 'R', 'I', 'O' };
    int length = chars.length;


    for (int line=0;line<=length;line++) {
        //This will print upper part of pyramid
        if(line < length/2){
            String output="";
            int middelVal=length/2;
            for (int i = middelVal - line; i > 0; i--) {
                output=output+" ";
            }
            for (int i = middelVal - line; i <= middelVal + line; i++) {
                output=output+chars[i];
            }
            System.out.println(output);
        }else if(line > length/2){
            //This will print lower part of pyramid
            String output="";
            int middelVal=length/2;
            int nwNum = chars.length-line;
            for (int i = middelVal - nwNum; i > 0; i--) {
                output=output+" ";
            }
            for (int i = middelVal - nwNum; i <= middelVal + nwNum; i++) {
                output=output+chars[i];
            }
            System.out.println(output);
        }
    }

获取中间索引,将其存储在两个变量中将标记开始和结束字符打印的位置。

int mid = length / 2; // left end
int midLen = mid;     // right end

循环将开始打印空间,直到左端mid ,然后打印字符,直到右端midLen + 1 然后将midLen增加到更右边,然后减少mid进一步向左。

for(int i = mid; mid > -1; mid--, midLen++) {
    for(int s = 0; s < mid; s++)
        System.out.print(" ");

    for (int j = mid; j < midLen + 1; j++) {
        System.out.print(chars[j]);
    }
    System.out.print("\n");
}

要打印下金字塔,我们将从0索引到length 这一次,我们增加mid进一步向右,然后递减midLen再往左,截断每行的字符串直到中间字符。

mid = 0;
midLen = length;

for(int i = mid; midLen != length / 2; mid++, midLen--) {

    for(int s = 0; s < mid; s++)
        System.out.print(" ");

    for(int j = mid; j < midLen; j++) {
        System.out.print(chars[j]);
    }
    System.out.print("\n");
}

在这里测试

奖励:利用Java 8的新功能 同样的机制,我会留给你检查。

...
static int mid;
static int midLen;
static String line = "";

public static void main(String[] args) {
    char[] chars = {'F', 'E', 'L', 'I', 'Z', ' ', 'A', 'N','I', 'V', 'E', 'R', 'S', 'A', 'R', 'I', 'O'};

    mid = chars.length / 2;
    midLen = mid;

    List<String> tri = new ArrayList<String>();
    IntStream.rangeClosed(0, mid)
        .forEach(i -> {
            Stream.of(chars).forEach( j -> {
                IntStream.range(0, mid).forEach(x -> line += " ");
                IntStream.rangeClosed(mid, midLen)
                    .forEach(x -> line += String.valueOf(chars[x]));
                mid--;
                midLen++;
                tri.add(line);
                line = "";
            });
         });

    tri.forEach(System.out::println); // print upper pyramid
    Collections.reverse(tri);
    tri.forEach(System.out::println); // print lower pyramid
}
...

这是使用2d数组的另一种方法

    char[] chars = { 'F', 'E', 'L', 'I', 'Z', ' ', 'A', 'N', 'I', 'V', 'E', 'R', 'S', 'A', 'R', 'I', 'O' };
    int size = chars.length;
    int mid = size / 2 + 1;
    char[][] matrix = new char[size][size];
    for (char[] cs : matrix) {
        Arrays.fill(cs, ' ');
    }
    for (int i = 0; i < size; i++) {
        int l = Math.abs(mid - 1 - i);
        int r = size - l;
        for (int m = l; m < r; m++) {
            matrix[i][m] = chars[m];
        }
    }
    for (char[] cs : matrix) {
        System.out.println(cs);
    }

产量

        I        
       NIV       
      ANIVE      
      ANIVER     
    Z ANIVERS    
   IZ ANIVERSA   
  LIZ ANIVERSAR  
 ELIZ ANIVERSARI 
FELIZ ANIVERSARIO
 ELIZ ANIVERSARI 
  LIZ ANIVERSAR  
   IZ ANIVERSA   
    Z ANIVERS    
      ANIVER     
      ANIVE      
       NIV       
        I        

这是我的头脑,但我尝试的一种方法是这样的:

找到数组中中间字符的索引。 称之为'startIndex'

对于每一行,我会找到长度,除以2(向下舍入),这将是startIndex的起始偏移,它决定了我的第一个字符是什么。

让我们说我在第5行,你有“Z ANIVERS”。 长度为9.除以2(向下舍入),得到4。

在chars数组中,startIndex计算为8(17/2,向下舍入)。 因此,我应该从char数组中的char 4(即startIndex - 4)开始打印,直到需要很多字符。

您也可以轻松打印整行而不计算循环中的字符,因为如果您知道所需的行长度和起始字符索引,那么如果您将初始字符作为一个字符串,则可以将该行一行子串。

最后,你也可以只完成一半的工作,因为看起来你的上半部分与下半部分相同(在字符串中构建结果然后将它们连接在一起以打印出完整的结果)

编辑:阅读我的答案,你不需要实际“找到”行长度,因为它只是从1开始,每次增加2,但原始方法仍然是相同的。

编辑2:

由于每个人都在添加他们的编码版本(并且答案已被接受),我不妨按照我的说法添加我的:

    String sourceString = "FELIZ ANIVERSARIO"; // source of characters
    String padding = "        "; // used to create the padding offset for each line

    int middle = sourceString.length() / 2;

    // top and bottom halves of the output
    String top = "";
    String bottom = "";

    for(int currentLength = 1; currentLength < sourceString.length(); currentLength += 2){
        String linePadding = padding.substring(currentLength / 2, padding.length());

        // speical case here, in the given example by the post, the 4th line the offset is one less as the I characters do not line up in the middle
        // 7 is used as the 4th line has a length of 7
        if(currentLength == 7){
            linePadding = linePadding.substring(1, linePadding.length());
        }

        top += linePadding + sourceString.substring(middle - (currentLength / 2), middle + (currentLength / 2) + 1) +"\n";
        bottom = linePadding + sourceString.substring(middle - (currentLength / 2), middle + (currentLength / 2) + 1) + "\n" + bottom;
    }

    System.out.println(top + sourceString +"\n"+ bottom);

不确定这是否是故意的,但我在循环中添加了一个特殊的期望,我在用户的例子中注意到第4行是1(我不在那里排队)。 如果我应该排队并且这是一个拼写错误,可以删除那个if block。

暂无
暂无

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

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