我有一个程序,它从文件中读取一对整数并将其存储在我创建的 Point 类中。第一个整数是文件每一行的 x 坐标,第二个整数是 y 坐标。所有有效点的x 坐标在 [0, 40] 范围内,y 坐标在 [1, 20] 范围内。
The input file contains data like this:
我执行了一些验证检查,以便我的程序忽略无效数据或超出范围的数据。
然后我必须在这些点之上绘制一条回归线。 我必须使用 2D 字符数组,并且更喜欢使用 Java 的 Point2D 类或 java 的其他一些图形类来这样做。
“X”表示点,“-”表示回归线段,“”表示线段和点位于同一点*
用于回归线的公式是这样的:
# 编辑#
下面是我从 @sprinter 获得的代码片段:
initializeArray(charArray);
int xySum = 0;
int xSqSum = 0;
int xSum = 0;
int ySum = 0;
for (Point points: point) {
xySum += points.getX() * points.getY();
xSqSum += points.getX() * points.getX();
xSum += points.getX();
ySum += points.getY();
}
int xMean = xSum / count;
int yMean = ySum / count;
int n = point.size();
int slope = (xySum - n* xMean * yMean) / (xSqSum - n * xMean * xMean);
for (Point points: point) {
charArray[points.getX()][points.getY()] = 'X';
}
// plot the regression line
for (int x = 0; x <charArray.length; x++) {
int y = yMean + slope * (x - xMean); // calculate regression value
charArray[x][y] = charArray[x][y] == 'X' ? '*' : '-';
}
这是我运行sprinter代码后程序的输出:
这也是我初始化 charArray 的方式:
public static void initializeArray(char[][] charArray) {
for(int k =0; k< charArray.length; k++) {
for(int d = 0; d<charArray[k].length;d++) {
charArray[k][d] = ' ';
}
}
}
这是新的输出:
最佳答案
我发现很难理解 fillArray
函数应该做什么。您的点列表中的每个“x”值可以有多个“y”值,因此我假设您为每个点调用一次。但是回归线有很多不在点列表中的“x”值,这意味着您必须为每个回归点调用一次。您也不需要在填充值后返回数组。
你的斜率计算似乎与公式根本不相符。这对我来说更有意义:
float xySum = 0;
float xSqSum = 0;
float xSum = 0;
float ySum = 0;
for (Point point: points) {
xySum += point.x * point.y;
xSqSum += point.x * point.x;
xSum += point.x;
ySum += point.y;
}
float xMean = xSum / count;
float yMean = ySum / count;
float n = points.size();
float slope = (xySum - n* xMean * yMean) / (xSqSum - n * xMean * xMean);
我怀疑绘制所有点然后绘制回归线会更好。
List<Point> points = ...;
// first plot the points
for (Point point: points) {
array[point.x][point.y] = 'X';
}
// now plot the regression line
for (int x = 0; x < 40; x++) {
int y = Math.round(yMean + slope * (x - xMean));
array[x][y] = array[x][y] == 'X' ? '*' : '-';
}
顺便说一句,如果您熟悉 Java 8 流,那么您可以使用:
double n = points.size();
double xySum = points.stream().mapToDouble(p -> p.x * p.y).sum();
double xSqSum = points.stream().mapToDouble(p -> p.x * p.x).sum();
double xMean = points.stream().mapToDouble(p -> p.x).sum() / n;
double yMean = points.stream().mapToDouble(p -> p.y).sum() / n;
最后,x 维度是第一个维度,y 维度是第二个维度。因此,要打印,您需要首先迭代 y,而不是 x:
for (int y = 0; y < 20; y++) {
for (int x = 0; x < 40; x++) {
System.out.print(array[x][20-y-1]);
}
System.out.println();
}
关于java - 二维字符数组的格式化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40351928/