【问题标题】:Printing pyramid pattern out of characters用字符打印金字塔图案
【发布时间】:2016-11-30 01:31:20
【问题描述】:

我需要打印一个金字塔形状的字符数组。我到目前为止是这样的:

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

任何帮助将不胜感激。

【问题讨论】:

  • 也许循环遍历字符串每一行中的每个字符,但如果它不在要显示的中间段中,则打印一个空格?
  • 你可以得到中间索引,首先,它们在midStartmidEnd中存储了相同的值。然后递增midStart 并递减midEnd

标签: java loops for-loop


【解决方案1】:

您可以执行以下代码所示的相同操作。它将使用较少数量的 for 循环。我已经在代码中添加了内联 cmets 来遍历它。

    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);
        }
    }

【讨论】:

    【解决方案2】:

    这是另一种使用二维数组的方法

        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        
    

    【讨论】:

      【解决方案3】:

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

      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");
      }
      

      Test here

      奖励:利用Java 8's new features。同样的机制,我把检查留给你。

      ...
      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
      }
      ...
      

      【讨论】:

        【解决方案4】:

        这不是我的想法,但我会尝试的一种方法是这样的:

        在数组中找到我的中间字符的索引。将此称为“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(我不在那里排队)。如果我应该排成一行,但这是一个错字,可以将其完全删除。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-06-05
          • 1970-01-01
          • 1970-01-01
          • 2022-01-22
          • 1970-01-01
          • 2021-07-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多