java - 使用尽可能少的空间连续分布点
问题描述
我有一行最多可以包含N
点。我想x
使用尽可能少的空间从中心向外分布该行内的点。
我设法在行内均匀分布点,但它使用了所有可用空间。使用公式floor((i+0.5)*N/x)
,我得到以下结果,考虑N=9
:
4
2 6
1 4 7
1 3 5 7
0 2 4 6 8
0 2 3 5 6 8
0 1 3 4 5 7 8
0 1 2 3 5 6 7 8
0 1 2 3 4 5 6 7 8
以下是上述输出中显示的索引的示例图形表示:
我想基本上限制点从中心向外太远,所以我得到的结果更像:
4
3 5
3 4 5
2 3 5 6
2 3 4 5 6
1 2 3 5 6 7
1 2 3 4 5 6 7
0 1 2 3 5 6 7 8
0 1 2 3 4 5 6 7 8
以下是上述输出中显示的索引的示例图形表示:
我正在使用 Java,这是我当前的代码
int rowLength = 9;
for (int points = 0; points <= rowLength; points++) {
for (float i = 0; i < points; i++) {
double result = Math.floor((i + 0.5) * rowLength / points);
System.out.print((int) result + " ");
}
System.out.println();
}
我怎样才能最好地实现第二张图片中显示的结果,以便我的代码输出与第二个示例输出相匹配?
解决方案
好的,让我们看一下图片。对我来说,似乎有几行有共同点:
观察:
- 蓝线的中间点被填充,橙色线的中间为空。
- 蓝色的是奇数,橙色的是偶数。
- 左边的空间是
- 在奇数情况下:
(rowLength - points)/2
,例如 (9-1)/2 = 4 - 在偶数情况下:
(rowLength -points -1)/2
,例如 (9-2-1)/2 = 3
- 在奇数情况下:
让我们把它放到代码中。我在这里使用 C#,但 Java 应该非常相似:
int rowLength = 9;
for (int points = 0; points <= rowLength; points++) {
bool isOdd = points%2 == 1;
if (isOdd)
{
int spaceOnSide = (rowLength-points)/2;
for (int i=0; i<points;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
}
else // even
{
int spaceOnSide = (rowLength-1-points)/2;
for (int i=0; i<points/2;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
for (int i=points/2; i<points;i++)
{
Console.Write(""+(i+spaceOnSide+1)+" ");
}
}
Console.WriteLine();
}
正如观察告诉我们的那样,这是非常直截了当的。
鉴于该代码,我们可以使用一些技巧:
由于整数除法,该行
int spaceOnSide = (rowLength-1-points)/2;
给出相同的结果
int spaceOnSide = (rowLength-points)/2;
(没有-1)。
我们可以将奇数情况下的 for 循环分成两部分:
for (int i=0; i<points/2;i++) { Console.Write(""+(i+spaceOnSide)+" "); } for (int i=points/2; i<points;i++) { Console.Write(""+(i+spaceOnSide)+" "); }
起初这听起来适得其反,但请看第 3 步。
完成该更改后,奇数部分和偶数部分看起来非常相似。这真的是重复的代码。唯一的区别在于
+1
部分。我们可以在那里添加 if 语句作为三元运算符:对于 (int i=0; 我
如果你不喜欢三元运算符,你可以去掉它:
(isOdd?0:1)
等于
(points+1)%2
最后你的代码很简单
int rowLength = 9;
for (int points = 0; points <= rowLength; points++) {
int spaceOnSide = (rowLength-points)/2;
for (int i=0; i<points/2;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
for (int i=points/2; i<points;i++)
{
Console.Write(""+(i+spaceOnSide+(points+1)%2)+" ");
}
Console.WriteLine();
}
推荐阅读
- rabbitmq - 消息代理之间有什么区别?
- jquery - 点击事件上的按钮
- swift - 如何将字符串转换为日期,在 Swift 中只获取日期而不是时间?
- javascript - 如何防止浏览器后退按钮出现php页面?
- docker - mysqld 服务未在 docker run 上启动
- docker - 设置 docker auto build 以使用 docker-compose 文件
- ios - iOS客户端上的X转发
- javascript - 显示不同组件时如何保持语义-ui模式不关闭?
- hive - 将字符串的 Hive 数组转换为 int 数组
- vba - 搜索标题,复制粘贴值直到最后一行