[英]Determine rows/columns needed given a number
我有许多在运行时确定的控件(在这种情况下是图表)。 我想将它们放在一个具有适当行数和列数的网格中。 例如,
抱歉,我真的没有任何代码可以显示我的尝试。 我开始尝试确定平方根是否为整数,该数字是否可以被 2 整除等,并意识到我不知道如何解决这个问题。 但这就是我的想法:
如果有人能指出我正确的方向,我将不胜感激 - 或者如果我偏离基地建议不同的算法。
思路:如果平方根不是整数,把它取下,然后除以这个数,取下它。
int columns = (int)sqrt(number);
int lines = (int)ceil(number / (float)columns);
示例:21 => 列 = 4,行 = 6。
更新:奖金,它也适用于 sqrt(number) 是整数。 任何地方都没有四舍五入,并且值是正确的。
处理这个问题的“通常”方法是说总是有 N 列(不太经常,总是 N 行)。 然后问题就变成了取项目数除以 N,这就是您拥有的行数(如果有余数,则加一)。
更改网格的大小会导致用户界面混乱。 用户不会理解为什么网格的大小不断变化。 他们不会真的对此感到怀疑,但他们会被看似随机的变化弄糊涂。
如果你仍然想做你所说的,我认为你需要更好地定义你的问题。 网格上可以容纳的项目数量是否有上限? 是否有允许的最大列数? 例如,如果您允许 50 个项目,它们应该在 25 行 2 个项目中吗? 5 行 10 个项目? 10 行 5 个项目?
在某些时候,您必须水平滚动或说“最大列数为 X”。 如果您要强加最大数量的列,那么您最好只说“总会有 X 列”。
除非有令人信服的理由来执行您要求的可变维度网格,否则最好只修复列数。 它使代码变得非常简单,而不是一些复杂的 hack,并且它为您的用户提供了更加一致的界面。
感谢您的提问和回答!
这是翻译成Javascript的代码:
cols = Math.floor( Math.sqrt(totalTiles) );
rows = Math.ceil( totalTiles / cols );
快速检查@jv42 的解决方案效果很好:
public struct Grid
{
public int x;
public int y;
public Grid(int xx, int yy)
{
x = xx;
y = yy;
}
}
class Program
{
static void Main(string[] args)
{
Grid g0 = GetGrid(1); Debug.Assert(g0.x == 1 && g0.y == 1);
Grid g1 = GetGrid(4); Debug.Assert(g1.x == 2 && g1.y == 2);
Grid g2 = GetGrid(8); Debug.Assert(g2.x == 2 && g2.y == 4);
Grid g3 = GetGrid(9); Debug.Assert(g3.x == 3 && g3.y == 3);
Grid g4 = GetGrid(20); Debug.Assert(g4.x == 4 && g4.y == 5);
Grid g5 = GetGrid(30); Debug.Assert(g5.x == 5 && g5.y == 6);
Grid g6 = GetGrid(99); Debug.Assert(g6.x == 9 && g6.y == 11);
}
public static Grid GetGrid(int n)
{
int columns = (int)Math.Sqrt(n);
int lines = (int)Math.Ceiling(n / (double)columns);
return new Grid(columns, lines);
}
在 WPF 中,控件 UniformGrid 自动计算网格的行和列,而无需确定行和列。 例如:
<UniformGrid >
<Image Source="Images\Aquarium.jpg" Margin="5"/>
<Image Source="Images\Ascent.jpg" Margin="5" />
<Image Source="Images\Autumn.jpg" Margin="5"/>
<Image Source="Images\Crystal.jpg" Margin="5"/>
<Image Source="Images\DaVinci.jpg" Margin="5"/>
<Image Source="Images\Follow.jpg" Margin="5"/>
<Image Source="Images\Friend.jpg" Margin="5"/>
<Image Source="Images\Aquarium.jpg" Margin="5"/>
</UniformGrid>
结果=> 以 3 列 3 行显示图像
我有这个问题,但有一些特定的要求;
例如:
1 2 3
4 5 6
1 2 3
4 5
1 2 3 4
5 6 7
我想出了这个(PHP)函数,但我相信它可以改进:
<?php
function optimalColCount ($numItems, $maxCols = 4) {
$numCols = $numItems;
if ($numCols > $maxCols and $maxCols === 2) {
$numCols = 2;
}
else if ($numCols > $maxCols) {
$numCols = sqrt($numItems);
if (!is_int($numCols) or $numCols > $maxCols) {
$numCols = -1;
for ($i = $maxCols; $i > 2; $i--) {
if ($numItems % $i === 0) {
$numCols = $i;
break;
}
}
if ($numCols === -1) {
$rests = [];
for ($i = $maxCols; $i > 2; $i--) {
$rests[$i] = $numItems % $i;
}
$numCols = array_search(max($rests), $rests);
}
}
}
return $numCols;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.