背景:
我已经成功编写了生成 0 到 2pi 正弦波的代码。调整常量 xPrecision
和 yPrecision
,您可以水平或垂直拉伸(stretch)图形。
当 xPrecision = yPrecision = 10
时,我获得了这个整洁的输出(在 Eclipse 中):
我的查询:
我现在希望显示数字 0 到 9 而不是星星。因此,最左边的星星被 0 替换,第二个最左边的星星被 1 替换,依此类推。当您达到 9 时,下一位数字再次为零。
我不知道该怎么做。我看过波浪模式 like this ,但它们是固定宽度的图案,而我的图案是可缩放的。
我能想到的唯一方法是将我的输出转换为二维字符数组,然后从左到右手动抓取 *
,并用数字替换它们,然后打印它。但是,当 x/yPrecision
的值较大时,这会非常消耗内存。
What is the most optimized way to achieve this output?
打印正弦波的代码:
class sine {
static final double xPrecision = 10.0; // (1/xPrecision) is the precision on x-values
static final double yPrecision = 10.0; // (1/yPrecision) is the precision on y-values
static final int PI = (int) (3.1415 * xPrecision);
static final int TPI = 2 * PI; // twice PI
static final int HPI = PI / 2; // half PI
public static void main(String[] args) {
double xd;
for(int start = (int) (1 * yPrecision), y = start; y >= -start; y--){
double x0 = Math.asin(y / yPrecision),
x1 = bringXValueWithinPrecision(x0),
x2 = bringXValueWithinPrecision(x0 + TPI / xPrecision),
x3 = bringXValueWithinPrecision(PI/xPrecision - x0);
// for debug
//System.out.println(y + " " + x0 + " " + x1 + " " + x2 + " " + x3);
for(int x = 0; x <= TPI; x++){
xd = (x / xPrecision);
if(x1 == xd || x2 == xd || x3 == xd)
System.out.print("*");
else System.out.print(" ");
}
System.out.println();
}
}
public static double bringXValueWithinPrecision(double num){
// obviously num has 16 floating points
// we need to get num within our precision
return Math.round(num * xPrecision) / xPrecision;
}
}
最佳答案
首先在内存中“绘制”图形,然后将数字分配给其垂直点,并在单独的 pass 中打印它们。
01
9 2
8 3
7 4
6 5
5 6
4 7
3 8
2 9
1 0
0 1 2
2 1
3 0
4 9
5 8
6 7
7 6
8 5
9 4
0 3
12
请参阅代码中的注释以了解其工作原理:
static final double xPrecision = 10.0; // (1/xPrecision) is the precision on x-values
static final double yPrecision = 10.0; // (1/yPrecision) is the precision on y-values
static final int PI = (int) (3.1415 * xPrecision);
static final int TPI = 2 * PI; // twice PI
static final int HPI = PI / 2; // half PI
public static void main(String[] args) {
// This part is the same as OP's code, except that instead of printing '*'
// it stores the corresponding row number in the array of rows
double xd;
int[] row = new int[100];
Arrays.fill(row, -1);
int r = 0;
int maxc = 0; // Mark the rightmost column of all iterations
for(int start = (int) (1 * yPrecision), y = start; y >= -start; y--){
double x0 = Math.asin(y / yPrecision),
x1 = bringXValueWithinPrecision(x0),
x2 = bringXValueWithinPrecision(x0 + TPI / xPrecision),
x3 = bringXValueWithinPrecision(PI/xPrecision - x0);
int c = 0;
for(int x = 0; x <= TPI; x++, c++){
xd = (x / xPrecision);
// This is where the asterisk used to go
if(x1 == xd || x2 == xd || x3 == xd)
row[c] = r;
}
maxc = Math.max(c, maxc);
r++;
}
// Walk the assigned rows, and give each one a consecutive digit
int[] digit = new int[100];
int current = 0;
for (int i = 0 ; i != 100 ; i++) {
if (row[i] != -1) {
digit[i] = (current++) % 10;
}
}
// Now walk the rows again, this time printing the pre-assigned digits
for (int i = 0 ; i != r ; i++) {
for (int c = 0 ; c != maxc ; c++) {
if (row[c] == i) {
System.out.print(digit[c]);
} else {
System.out.print(' ');
}
}
System.out.println();
}
}
public static double bringXValueWithinPrecision(double num){
// obviously num has 16 floating points
// we need to get num within our precision
return Math.round(num * xPrecision) / xPrecision;
}
代码的第一部分填充row[i]
数组,其中包含i
列中星号的行。 row[]
数组中的前几个数字如下所示:
10 9 8 7 6 5 4 - 3 2 - 1 - - - 0 0 - - - 1 - 2 3 - 4 5 6 7 8 9 10
-
表示带有-1
的单元格,表示缺失值。该数组表明最左边的星号位于第 10 行,下一个星号位于第 9 行,然后是第 8、7、6 行,依此类推。星号 11 和 12 位于顶部的第 0 行。
第二个循环遍历行
,跳过-1
,并将连续数字分配给所有非负数位置。
第三个循环再次逐行遍历整个字段,当当前行与 row[] 中的值匹配时,打印来自预先分配的
数组。digit[]
数组的值
关于java - 按正弦波顺序打印数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48208510/