二维数组字符格式

时间:2016-10-31 19:06:18

标签: java arrays multidimensional-array graph formatting

所以我正在编写一个程序,我必须从包含坐标点的文件中读取,然后显示该图。例如,我将此作为第一行,20 10.我的程序应该做的是使用2D数组字符绘制它。一个' X'将被用于分数。

这是我计算回归线的斜率和公式的方法。

enter image description here

  float xMean = xSum / count;
  float yMean = ySum / count;
  float n = count;
  float slope = (xySum - n* xMean * yMean) / (xSqSum - n * xMean * xMean);

我使用以下方法打印' - '如果没有' X' char,如果有一个' *'焦炭。

for (int i = 0; i < graph.length; i++) {
      int yPred = Math.round(yMean + slope * (i - xMean)); // calculate regression value
        graph[21-1-yPred][i + 1] = graph[21-1-yPred][i + 1 ] == 'X' ? '*' : '-';
    }

我正在瞄准的正确输出

Scatterplot using 2D array of characters

但是我得到了这个输出:

enter image description here

我想要实现的是我的程序会打印&#34; - &#34; s作为回归线段,&#34; *&#34; s其中一个线段和一个点位于同一地点

  

然而,与正确的输出相比,我的程序中的破折号越来越少。星号也不在它应该的中间位置。

这是我正在使用的文本文件。我能够通过我的程序完成验证。 ** [0,40]范围内的x坐标和[1,20]范围内的y坐标。** enter image description here

2 个答案:

答案 0 :(得分:2)

好吧,让我们解决这个问题吧!首先,花了15分钟左右将线条放到屏幕截图文本文件中,这里是我绘制的图像(当然描绘了原始图像):

orig img with line markup

现在,你提到了一个&#39; X&#39;你要画画。这也是一个文本文件,您可以从文件中读取它,所以这就是所说的文件(让我们称之为&#39; coords.txt & #39;为了这个例子)。

20 10

enter image description here

根据我所做的线叠加图像,20和10是读取的坐标,我认为(20 10)将与x轴= 21相关,y轴= 10(可能是一个关闭通过一个错误进行简单的索引 - 阅读更多here 我基本上只是将图形视为图形)。

这是从文件中读取该点/数据并准备绘制的一种方法: 通过

从文件中读取20 10
Scanner s = new Scanner(new File("coords.txt"));
int x = 0;
int y = 0;
if (s.hasNext())
    x = s.nextInt();
if (s.hasNext())
    y = s.nextInt();
s.close();

该代码很简单,因为它使Scanner对象读取我们文件的内容。然后,声明xy整数以存储我们的坐标值。注意:s.hasNext()通常是有价值的逻辑,用于检查文本文件中的某些内容,以便在尝试阅读之前阅读 - 您还可以调整s.hasNextInt()以便只向前看接下来是从文件中读取的整数标记。

但是,我注意到你的结果图上有几个X-marks-the-spot。通过回到图像,我在视觉上看到了您未明确提及的那些坐标&#39; coords.txt &#39;文件,让我们说在这个例子中你将有一个包含以下行的文件:

20 10
0 1
40 20
13 17
10 20

现在这些数字是基于原始图像我绘制了线条,但是我尊重了一个一个错误,这就是为什么它们不直接与该图像上的坐标相关联,因为为了纠正那个一个一个错误。

现在有几个coords,如何以更有效的方式阅读输入?这是解决问题的唯一方法:

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class App {
    public static final int SIZE = 100;
    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(new File("C:\\Users\\Nick\\Desktop\\coords.txt"));
        int x = 0;
        int y = 0;
        int[] xCoords = new int[SIZE];
        int[] yCoords = new int[SIZE];
        int index = 0;
        while (s.hasNextLine()) {
            if (s.hasNextInt()) {
                x = s.nextInt();
            } else {
                System.out.println("had a next line, but no integers to read");
                break;
            }
            if (s.hasNextInt()) {
                y = s.nextInt();
            } else {
                System.out.println("had a next line, but no integers to read");
                break;
            }
            xCoords[index] = x;
            yCoords[index] = y;
            index++;
        }
        s.close();
    }
}

此代码假定了几件事,包括;

  1. 我们认为我们不会阅读超过100个坐标来绘图。 (如果您确实知道这个数字,只需将SIZE值修改为预先确定的值。如果您不知道该值,请查看growing/expanding an arrayjava.util.List, java列表界面上的tutorial
  2. xCoordsyCoords整数数组匹配/镜像,因为它们都应该在给定索引处填充,以便表示可绘图的坐标(X-marks-the-spot)
  3. 同样也是前一点,在while循环中,每行被认为包含两个读取的整数值,类似于一个坐标。
  4. 每个循环后整数index值增加,以帮助准备下一个读入点,并让我们知道在while循环循环时读取了多少个点。
  5. 运行以上代码以阅读&#39; coords.txt &#39;文件,并在while循环之后但在System.out.println()帮助显示读取内容之前添加一些简单的s.close();。 这是输入读数的第二个版本,以及显示发生的事情的输出:

    import java.io.File;
    import java.io.IOException;
    import java.util.Scanner;
    
    public class App {
        public static final int SIZE = 100;
        public static void main(String[] args) throws IOException {
            Scanner s = new Scanner(new File("C:\\Users\\Nick\\Desktop\\coords.txt"));
            int x = 0;
            int y = 0;
            int[] xCoords = new int[SIZE];
            int[] yCoords = new int[SIZE];
            int index = 0;
            while (s.hasNextLine()) {
                if (s.hasNextInt()) {
                    x = s.nextInt();
                } else {
                    System.out.println("had a next line, but no integers to read");
                    break;
                }
                if (s.hasNextInt()) {
                    y = s.nextInt();
                } else {
                    System.out.println("had a next line, but no integers to read");
                    break;
                }
                xCoords[index] = x;
                yCoords[index] = y;
                index++;
            }
            System.out.println("Output from what was read in from file:");
            for (int i = 0; i < index; ++i) {
                System.out.print(xCoords[i] + ", ");
                System.out.println(yCoords[i]);
            }
            s.close();
        }
    }
    

    各自的输出:

    had a next line, but no integers to read
    Output from what was read in from file:
    20, 10
    0, 1
    40, 20
    13, 17
    10, 20
    

    前两行只是可以删除的注释。很高兴看到我们能够有效地阅读我们的数据!

    转到问题的面包和部分,全部输出。为了输出示例图像,我们需要有效地打印出一个2D字符阵列(至少这是我在这里用来解释的想法)。

    我们知道(基于行标记图表)我们需要具有21 x 42的尺寸才能获得完整的副本输出。这是因为轴标记本身。所以,让我们开始宣布一个像以下的2D数组:

    char[][] graph = new char[21][42];
    

    太棒了!我们有一张无形的图表!让我们把那些可怜的空字符拿出去,并把一些好的旧空间放进去!毕竟,这是将所有内容打印出来的根本原因,您不能期望char的{​​{1}}值与'\0'的行为相同。

    ' '

    现在让我们开始用裸轴标记它。首先是y轴:

    for (int i = 0; i < graph.length; ++i)
        for (int j = 0; j < graph[0].length; ++j)
            graph[i][j] = ' ';
    

    注意:我们可以使用for (int i = 0; i < graph.length; ++i) { graph[i][0] = '/'; } graph[20][0] = '+'; 符号作弊,因为它最终会出现。 for循环可以使用+语句并使用if标记最后一个索引,但也可以尝试直观。

    然后,对于x轴:

    +

    由于我们知道最终的位置,我们只需使用20的硬编码值并循环索引以输入x轴符号/ char for (int i = 1; i < graph[0].length; ++i) { graph[20][i] = '-'; }

    让我们看看这个新创建的图表,其中包含以下代码:

    -

    哪个应产生以下输出:

    for (int i = 0; i < graph.length; ++i) {
        for (int j = 0; j < graph[0].length; ++j) {
            System.out.print(graph[i][j]);
        }
        System.out.println();
    }
    

    现在,根据您使用前面代码中坐标的内容,绘制X-marks-the-spot。

    这可以通过循环镜像整数数组(/ / / / / / / / / / / / / / / / / / / / +----------------------------------------- xCoords)并使用这些坐标绘制到2D yCoords来完成。

    char[][] graph

    分解这里的信息(上图),for (int i = 0; i < index; ++i) { graph[21 - 1 - yCoords[i]][xCoords[i] + 1] = 'X'; } 意味着通过使用从向后描绘的图的顶部值的偏移量将y坐标转换为2D阵列中表示的相应点(因此使用21从顶部开始)和另一个减去一个偏移因为轴本身(例如&#39; /&#39;和&#39; - &#39;和&#39; +&#39; ;字符分别)。对于[21 - 1 - yCoords[i]],简单加一个用于轴本身偏移。

    这是输出:

    xCoords

    看起来非常像那些输出被假设的图片的早期阶段!

    总而言之,这就是我的最终代码:

    /          X                             X
    /                                         
    /                                         
    /             X                           
    /                                         
    /                                         
    /                                         
    /                                         
    /                                         
    /                                         
    /                    X                    
    /                                         
    /                                         
    /                                         
    /                                         
    /                                         
    /                                         
    /                                         
    /                                         
    /X                                        
    +-----------------------------------------
    

    如果您想要包含更多细节,例如多个&#39; - &#39;回归和&#39; *&#39;为了这一点,我鼓励使用这些信息来学习和适应阅读那些附加信息的坐标并将其应用于这个例子。但是,没有提供相关的信息,因此我不会冒险使用涉嫌文本文件和协调的主题,要么将其编辑到问题中,要么自己尝试并学习一些东西。 :)干杯

答案 1 :(得分:1)

为什么不只是array[x][y] = 'X';

另外,你在阵列的其余部分放置了什么?如果你不在那里放任何东西,它默认为0,在终端上显示为什么都没有。我猜你想用空格和换行符填充未使用的条目