Java三角类直方图

时间:2016-11-21 22:30:10

标签: java histogram

我需要一个项目的帮助,我想创建一个java程序,它创建一种三角形的直方图,很难解释所以看看下面的例子

add_filter('upload_dir', 'my_upload_dir');
$wp_upload = wp_upload_dir();
function my_upload_dir($wp_upload) {
    $wp_upload['basedir'] = '/usr/home/myhiddendir/';
    $wp_upload['baseurl'] = '../myhiddendir/';
    $wp_upload['subdir'] = '';
    $wp_upload['path'] = $wp_upload['basedir'] . $wp_upload['subdir'];
    $wp_upload['url']  = $wp_upload['baseurl'] . $wp_upload['subdir'];

    return $wp_upload;
}

在我的代码中我设法创建了输入部分和基础的生成器,但是三角形/ piramides生成器没有制作正确的空格,任何人都可以帮助我吗? 这是我制作三角形的代码(假设输入是数组数字 numbers2 ):

input : 3 1 12 0 7
output:

                           _
                          /|\
                         / | \
                        /  |  \
                       /   |   \
                      /    |    \                   _
                     /     |     \                 /|\
                    /      |      \               / | \
                   /       |       \             /  |  \
    _             /        |        \           /   |   \
   /|\           /         |         \         /    |    \
  / | \    _    /          |          \       /     |     \
 /  |  \  /|\  /           |           \  _  /      |      \
<=======><===><=========================><=><===============>
 |     |  | |  |                       |  |  |             |

我的输出结果如下:

public class Spires{
    public static void main(String[] args){
    int[] numbers = {3,1,12,0,7};
    int counter = 6, max = 12;
    int[] numbers2 = {3,1,12,0,7};

        for(int row = max+1; row >= 0; --row) {
            System.out.println();
            for(int col = 0; col < counter-1; ++col) {
                if(numbers2[col] >= row){
                        for(int spacesleft = 1; spacesleft < (numbers2[col] + col)+row-1; ++spacesleft){
                            System.out.print(" ");
                        }
                    if(numbers2[col] != row){
                        System.out.print("/");
                        for(int c3 = 0; c3 < numbers2[col]-row-1; ++c3) {
                            System.out.print(" ");
                        }
                        System.out.print("|");
                        for(int c3 = 0; c3 < numbers2[col]-row-1; ++c3) {
                            System.out.print(" ");
                        }
                        System.out.print("\\");

                    }else{
                        System.out.print("_");
                    }
                    // for(int spacesright = 1; spacesright <  numbers2[col] + col + row -1; ++spacesright){
                        // System.out.print(" ");
                    // }                    
                }
            }
        }
        System.out.println();
                        //base generator
        for(int i = 0; i<counter-1; ++i) {
            System.out.print("<");
            for(int i2 = 0; i2 < 2*numbers[i]+1; ++i2)  {
                System.out.print("=");
            }
            System.out.print(">");
        }       
        System.out.println();

        for(int i = 0; i<counter-1; ++i) {
            if(numbers[i] != 0){
                System.out.print(" |");
                for(int i2 = 0; i2 < 2*numbers[i]-1; ++i2)  {
                    System.out.print(" ");
                }
                System.out.print("| ");
            }else{
                System.out.print(" | ");
            }
        }
    }
}

我需要一些帮助,找出如何添加缺少的空格并删除一些

2 个答案:

答案 0 :(得分:3)

你快到了!只需要做一些调整就可以了。

  1. 三角形腿左侧和右侧外部空间数量的计算实际上非常简单:row + 1。因为每个三角形都是从下向上构建的,所以第0行(底行)上显示的三角形需要1个空格,第1行需要2个空格等。
  2. 如果当前row位于您正在显示的三角形列的“上方”,则仍需要输出空格以标记该三角形的占位符。因此,if (numbers2[col] >= row)需要相应的else才能显示空格。
  3. 应用这两个更改就像:

     if(numbers2[col] >= row){
    
        //            corrected calculation \-------/
        for(int spacesleft = 0; spacesleft < row + 1; ++spacesleft){
            System.out.print(" ");
        }
    
         if(numbers2[col] != row){
             System.out.print("/");
             for(int c3 = 0; c3 < numbers2[col] - row - 1; ++c3) {
                 System.out.print(" ");
             }
             System.out.print("|");
             for(int c3 = 0; c3 < numbers2[col] - row - 1; ++c3) {
                 System.out.print(" ");
             }
             System.out.print("\\");
    
         }else{
             System.out.print("_");
         }
    
         //              corrected calculation \-------/
         for(int spacesright = 0; spacesright < row + 1; ++spacesright){
             System.out.print(" ");
         }
    
     // output spaces to fill area for that column and shift everything over properly
     } else {
        for (int spaces = 0; spaces < numbers2[col] * 2 + 3; spaces++)
            System.out.print(" ");
     }
    

    这应该按预期输出直方图。

    现在我想请您考虑为什么这段代码难以使用。与您一次掌握的变量和想法的数量直接相关,难以阅读和理解一段代码。

    使这段代码更易于推理的一种方法是将其分解为可以单独处理问题的不同方面的不同函数。例如,我们可能会添加以下方法:

    1. 打印一定数量的空格
    2. 打印一行三角形
    3. 使用更多具有直观名称的变量也很有帮助,因此您无需在整个计算过程中保持推理。这是一个应该证明的例子:

      // output 'count' spaces
      public static void printSpaces(int count) {
          for (int spaces = 0; spaces < count; spaces++) System.out.print(" ");
      }
      
      // output one row of a triangle based on supplied height
      // and current display row, starting at 0=top row.
      public static void printTriangleSection(int triangleHeight, int rowOfTriangle) {
      
          int triangleWidth = triangleHeight * 2 + 3; // total width taken up by this triangle
          int halfWidth = triangleHeight + 1;     // total width taken up by one side (excluding the middle)
      
          int spacesOutside = halfWidth - rowOfTriangle;  // total spaces outside of triangle hypotenuse
          int spacesInside = rowOfTriangle - 1;           // total spaces inside triangle hypotenuse
      
          if (rowOfTriangle < 0) {        // above the first row of the triangle
              printSpaces(triangleWidth);
          } else if (rowOfTriangle == 0) {
              printSpaces(spacesOutside);
              System.out.print("_");
              printSpaces(spacesOutside);
          } else {
              printSpaces(spacesOutside);
              System.out.print("/");
              printSpaces(spacesInside);
              System.out.print("|");
              printSpaces(spacesInside);
              System.out.print("\\");
              printSpaces(spacesOutside);
          }
      }
      

      然后,main方法的相关部分将简化为:

      for(int row = max+1; row >= 0; --row) {
         System.out.println();
         for(int col = 0; col < counter-1; ++col) {
             printTriangleSection(numbers2[col], numbers2[col] - row);
         }
      }
      

答案 1 :(得分:2)

简介

我提供这个答案的原因是写下如何推理编码问题。三角直方图非常有趣,我可以找到解决方案。

这是一次试运行:

Enter the heights of the triangles: 3 1 12 0 7

                           -                                 
                          /|\                                
                         / | \                               
                        /  |  \                              
                       /   |   \                             
                      /    |    \                   -        
                     /     |     \                 /|\       
                    /      |      \               / | \      
                   /       |       \             /  |  \     
    -             /        |        \           /   |   \    
   /|\           /         |         \         /    |    \   
  / | \    -    /          |          \       /     |     \  
 /  |  \  /|\  /           |           \  -  /      |      \ 
<=======><===><=========================><=><===============>
 |     |  | |  |                       |  |  |             | 

Enter the heights of the triangles: 

推理

输入三角形的高度,并输出直方图三角形。按Enter键而不键入任何数字可让程序知道退出。

当我查看直方图时,我注意到了3件事。

  1. 我可以创建一个Java类来形成三角形,并为我需要绘制的每个三角形创建一个类的实例。在示例测试运行中,我创建了5个三角形,因此我创建了5个类的实例。

  2. 如果我先创建基行,我可以使用&lt;的定位。和&gt;计算从哪里开始三角形边的标志。

  3. 直方图从下往上比从上到下更容易创建。

  4. 现在,它有很多帮助,我知道我可以使用StringBuilder创建一个空字符串,并使用setCharAt方法将字符放在空白字符串中。这样,我就不必计算三角形之间和中间的空白数量。

    我知道我可以使用List来存储输出字符串,并按照创建它们的相反顺序打印它们,这也有很多帮助。

    所以,这里&#39;我可以给你解决编码问题的第一个提示。

      

    如果事情看起来很难实现,请问某人是否有更简单的方法。

    可能没有更简单的方法。一些编码问题很难。但有时,您可能没有意识到更容易的解决方案。

    所以,这是生成直方图的代码。

    package com.ggl.testing;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    public class TriangleHistogram implements Runnable {
    
        public static void main(String[] args) {
            new TriangleHistogram().run();
        }
    
        @Override
        public void run() {
            Scanner scanner = new Scanner(System.in);
            List<TriangleModel> triangleHistogram = readInput(scanner);
    
            while (triangleHistogram.size() > 0) {
                String baseString = createBaseString(triangleHistogram);
                String bottomString = createBottomString(triangleHistogram,
                        baseString.length());
    
                List<String> histogramStrings = new ArrayList<>();
                histogramStrings.add(bottomString);
                histogramStrings.add(baseString);
                createTriangleStrings(triangleHistogram, histogramStrings);
    
                displayHistogram(histogramStrings);
    
                triangleHistogram = readInput(scanner);
            }
    
            scanner.close();
        }
    
        private List<TriangleModel> readInput(Scanner scanner) {
            List<TriangleModel> triangleHistogram = new ArrayList<>();
            System.out.print("Enter the heights of the triangles: ");
            String inputLine = scanner.nextLine();
    
            if (!inputLine.trim().isEmpty()) {
                String[] triangleSizes = inputLine.split("\\s");
                for (int i = 0; i < triangleSizes.length; i++) {
                    TriangleModel triangleModel = new TriangleModel(
                            Integer.parseInt(triangleSizes[i]));
                    triangleHistogram.add(triangleModel);
                }
            }
    
            return triangleHistogram;
        }
    
        private String createBaseString(List<TriangleModel> triangleHistogram) {
            StringBuilder builder = new StringBuilder();
    
            for (TriangleModel triangleModel : triangleHistogram) {
                triangleModel.setColumns(builder);
                triangleModel.createBase(builder);
            }
    
            return builder.toString();
        }
    
        private String createBottomString(List<TriangleModel> triangleHistogram,
                int length) {
            StringBuilder builder = createStringBuilder(' ', length);
    
            for (TriangleModel triangleModel : triangleHistogram) {
                triangleModel.createBottom(builder);
            }
    
            return builder.toString();
        }
    
        private void createTriangleStrings(List<TriangleModel> triangleHistogram,
                List<String> histogramStrings) {
            String histogramString = "";
    
            do {
                String baseString = histogramStrings.get(1);
                StringBuilder builder = createStringBuilder(' ',
                        baseString.length());
    
                for (TriangleModel triangleModel : triangleHistogram) {
                    triangleModel.createTriangle(builder);
                }
    
                histogramString = builder.toString();
                histogramStrings.add(histogramString);
            } while (!histogramString.trim().isEmpty());
    
        }
    
        private StringBuilder createStringBuilder(char c, int length) {
            StringBuilder builder = new StringBuilder(length);
    
            for (int i = 0; i < length; i++) {
                builder.append(c);
            }
    
            return builder;
        }
    
        private void displayHistogram(List<String> histogramStrings) {
            for (int i = histogramStrings.size() - 1; i >= 0; i--) {
                String line = histogramStrings.get(i);
                System.out.println(line);
            }
    
            System.out.println();
        }
    
        public class TriangleModel {
            private final int height;
    
            private int leftColumn;
            private int centerColumn;
            private int rightColumn;
    
            public TriangleModel(int height) {
                this.height = height;
            }
    
            public void setColumns(StringBuilder builder) {
                this.leftColumn = builder.length() + 1;
                this.centerColumn = leftColumn + height;
                this.rightColumn = centerColumn + height;
            }
    
            public void createBase(StringBuilder builder) {
                builder.append('<');
                for (int i = 0; i < getBaseWidth(); i++) {
                    builder.append('=');
                }
                builder.append('>');
            }
    
            public void createBottom(StringBuilder builder) {
                builder.setCharAt(leftColumn, '|');
                builder.setCharAt(rightColumn, '|');
            }
    
            public void createTriangle(StringBuilder builder) {
                if (leftColumn < rightColumn) {
                    builder.setCharAt(leftColumn, '/');
                    builder.setCharAt(centerColumn, '|');
                    builder.setCharAt(rightColumn, '\\');
    
                    leftColumn++;
                    rightColumn--;
                } else if (leftColumn == rightColumn) {
                    builder.setCharAt(centerColumn, '-');
    
                    leftColumn++;
                    rightColumn--;
                }
            }
    
            private int getBaseWidth() {
                return height + height + 1;
            }
    
        }
    
    }
    

    说明

    我使主要的TringleHistogram类实现了Runnable,以便我可以将主代码放在run方法中。我不想在类的构造函数中放入大量代码。

    run方法是代码中发生的事情的概要。我从用户那里获得了高度,并创建了直方图。我首先创建基线,然后是底线,然后是相反顺序的三角形。

    run方法中的while循环使用priming读取。我在while循环之前调用readInput方法一次,在while循环结束时再调用一次。这样,当用户按下Enter键时,我不必跳过while循环的任何部分。

    readInput方法不进行任何错误检查。可以在readInput方法中添加错误检查。

    我将TriangleHistogram类中的代码分解为多个方法。每种方法都会执行方法名称所表达的方式。命名方法对描述性很重要。一般来说,我使用动词 - 名词构造。

    TriangleModel类绘制一个三角形。在课堂上看,并没有太多的数学。当我创建基线时,我设置左中心的列和三角形的右边部分。当我创建直方图的每一行时,我会调整左右列,直到它们在三角形的顶部相遇。

    你可以在TriangleModel方法中看到,将字符放在空白的StringBuilder上要比添加空格和字符简单得多。

    开发

    我没有一次写完整个节目。我写了一小部分程序并对它们进行了测试。写一点并测试一点的好处是,当你发现问题时,你很清楚代码中的问题在哪里。

    1. 我编写了readInput方法和足够的run方法来运行while循环。我写了足够的TriangleModel类来保持高度。除了处理输入,创建一个TriangleModel对象列表而不是崩溃之外,该程序没有做任何事情。不崩溃的部分是最重要的部分。

    2. 我将其余字段添加到TriangleModel类并创建了直方图的基线。最后,我可以看一些输出!耶!

    3. 我创建了直方图的底线。这使我能够确认三角形的左列和右列是否正确定义。

    4. 我在直方图的基础上创建了一行。这使我能够验证三角形的中心列是否已正确定义,输出字符串列表是否以相反的顺序创建和打印。

    5. 我写了剩下的代码。这是我的程序首先崩溃的地方。当它们相等时,我忘了调整左右列。我很快发现了问题,因为我知道问题出在新代码中。

    6. 然后我完成了。我花了一些时间来清理一些代码,并使字段名称和方法名称更具描述性。

      您可以学习这些编写代码的技巧。这是我能给你的最后一个提示。

        

      您没有为编译器编写代码。您正在编写代码,以便其他人(包括您自己3个月后)可以阅读并轻松理解代码。

      从广泛的想法开始,随着您进一步深入代码,深入了解越来越多的细节。

      我希望这个答案很有帮助。