C# 确定给定数字所需的行/列
我有许多在运行时确定的控件(本例中为图表)。我想把它们放在一个有适当行数和列数的网格中。比如说,C# 确定给定数字所需的行/列,c#,algorithm,silverlight,math,C#,Algorithm,Silverlight,Math,我有许多在运行时确定的控件(本例中为图表)。我想把它们放在一个有适当行数和列数的网格中。比如说, 4项=2 x 2 8项=4 x 2 9项=3 x 3 20项=5 x 4 11项=4 x 3(我不在乎空单元格) 抱歉,我没有任何代码来显示我的尝试。我开始尝试确定平方根是否是整数,数字是否可以被2整除等等,然后意识到我不确定如何解决这个问题。但这就是我的想法: 如果平方根是整数,则使用平方根表示行数和列数(没有问题) 如果不是,请确保数字为偶数(如果必须,请添加一个-没有问题) 找到生成该数
- 4项=2 x 2
- 8项=4 x 2
- 9项=3 x 3
- 20项=5 x 4
- 11项=4 x 3(我不在乎空单元格)
- 如果平方根是整数,则使用平方根表示行数和列数(没有问题)
- 如果不是,请确保数字为偶数(如果必须,请添加一个-没有问题)
- 找到生成该数字的最高两个整数。e、 g.如果我有20个控件,网格应该是5x4,而不是10x2(不确定最好的方式)
除非有令人信服的理由去做你要求的可变维度网格,否则你最好只是固定列的数量。它使代码变得非常简单,而不是复杂的黑客行为,并且它为用户提供了一个更加一致的界面。想法:如果平方根不是整数,将其加上下限,然后将整数除以它,将其除掉
int columns = (int)sqrt(number);
int lines = (int)ceil(number / (float)columns);
示例:21=>columns=4,lines=6
更新:奖金,当sqrt(数字)为整数时也有效。任何地方都不会进行舍入,并且值是正确的。快速检查@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>
1 2 3
4 5 6
1 2 3
4 5
1 2 3 4
5 6 7
结果=>以3列3行显示图像感谢您的提问和回答 下面是翻译成Javascript的代码:
cols = Math.floor( Math.sqrt(totalTiles) );
rows = Math.ceil( totalTiles / cols );
我有这个问题,但有一些具体的要求
- 列的数量永远不能超过一定的数量
- 如果项目的数量不完全符合一定数量的列,我希望尽可能多的寡妇
<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>
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;
}
是否有进一步的约束条件来帮助决定“更好”的匹配?例如,2x17=34,但使用5x7=35可以得到一个更“方形”的网格,其中缺少一个空间。当你开始考虑越来越大的素数的双倍时,这种情况可能会变得更糟。嗯,我没想过——谢谢你指出这一点。我想我更喜欢35个正方形,上面没有空格。谢谢!我在打字时确实重命名了vars,这是个坏主意;)的确我可能最终会采用这种方法。谢谢