问题:我们有x个复选框,我们想要均匀地检查它们。
示例1:选择50个总共100个复选框。
[-]
[x]
[-]
[x]
...
示例2:选择总共100个的33个复选框。
[-]
[-]
[x]
[-]
[-]
[x]
...
示例3:选择总共100个的66个复选框:
[-]
[x]
[x]
[-]
[x]
[x]
...
但我们很难想出一个公式来检查代码,特别是一旦你去了11/111或类似的东西。有人有想法吗?
答案 0 :(得分:4)
我们首先假设y
可以被x
整除。然后我们表示p = y/x
,解决方案很简单。浏览列表,每个p
个元素,标记其中的一个。
现在,让我们说 r = y%x
不为零。仍为p = y/x
,其中/
为整数分割。所以,你需要:
p-r
元素中,标记1个元素r
元素中,标记2个元素 注意:这取决于您如何定义均匀分布。您可能希望在r
个部分之间使用x+1
元素展开p-r
个部分和x
元素,这确实是同样的问题,可以递归解决。德尔>
好吧所以它实际上并不正确。我想这会做到:
无论可分性如何:
y > 2*x
,则每p = y/x
个元素标记1个元素,x
次。y < 2*x
,则标记全部,然后执行上一步操作y-x
y
复选框{与前一种情况相同,但x
被替换为y-x
p
) 注意:这取决于您如何定义均匀分布式。您可能希望在p+1
和{{1}}元素之间进行更改,例如更好地分发它们。
答案 1 :(得分:2)
这是使用整数运算的直接解决方案:
void check(char boxes[], int total_count, int check_count)
{
int i;
for (i = 0; i < total_count; i++)
boxes[i] = '-';
for (i = 0; i < check_count; i++)
boxes[i * total_count / check_count] = 'x';
}
total_count
是框的总数,check_count
是要检查的框数。
首先,它将每个框设置为未选中。然后,它会检查check_count
框,将计数器缩放到框数。
警告:这是偏向偏见而不是像你的例子那样偏右偏向。也就是说,它打印x--x--
而不是--x--x
。您可以通过替换
boxes[i * total_count / check_count] = 'x';
使用:
boxes[total_count - (i * total_count / check_count) - 1] = 'x';
假设0 <= check_count <= total_count
,并且boxes
至少有total_count
项的空间,我们可以证明:
没有复选标记会重叠。每次迭代时i * total_count / check_count
至少增加一次,因为total_count >= check_count
。
这不会溢出缓冲区。下标i * total_count / check_count
将是>= 0
。 i
,total_count
和check_count
都是>= 0
。
将是< total_count
。当n > 0
和d > 0
:
(n * d - 1) / d < n
换句话说,如果我们取n * d / d
并向下推动分子,那么商也会下降。
因此,(check_count - 1) * total_count / check_count
将小于total_count
,具有上述假设。不会发生除零,因为如果check_count
为0,则所讨论的循环将具有零迭代。
答案 2 :(得分:1)
Bresenham - 类似算法适合均匀分配复选框。 'x'的输出对应于Y坐标变化。可以在范围[0..places]中选择初始err作为随机值,以避免偏差。
def Distribute(places, stars):
err = places // 2
res = ''
for i in range(0, places):
err = err - stars
if err < 0 :
res = res + 'x'
err = err + places
else:
res = res + '-'
print(res)
Distribute(24,17)
Distribute(24,12)
Distribute(24,5)
output:
x-xxx-xx-xx-xxx-xx-xxx-x
-x-x-x-x-x-x-x-x-x-x-x-x
--x----x----x---x----x--
答案 3 :(得分:0)
快速html / javascript解决方案:
<html>
<body>
<div id='container'></div>
<script>
var cbCount = 111;
var cbCheckCount = 11;
var cbRatio = cbCount / cbCheckCount;
var buildCheckCount = 0;
var c = document.getElementById('container');
for (var i=1; i <= cbCount; i++) {
// make a checkbox
var cb = document.createElement('input');
cb.type = 'checkbox';
test = i / cbRatio - buildCheckCount;
if (test >= 1) {
// check the checkbox we just made
cb.checked = 'checked';
buildCheckCount++;
}
c.appendChild(cb);
c.appendChild(document.createElement('br'));
}
</script>
</body></html>
答案 4 :(得分:0)
从本月早些时候开始调整one question's answer或another answer的代码。设置 N = x =
数量的复选框以及要检查的 M = y =
数字,并为部分尺寸应用公式(N*i+N)/M - (N*i)/M
。 (另见Joey Adams的回答。)
在python中,改编的代码是:
N=100; M=33; p=0;
for i in range(M):
k = (N+N*i)/M
for j in range(p,k-1): print "-",
print "x",
p=k
产生
- - x - - x - - x - - x - - [...] x - - x - - - x
其中[...]代表25 --x
次重复。
使用M=66
代码
x - x x - x x - x x - x x - [...] x x - x x - x - x
其中[...]主要代表xx-
次重复,中间有一个x-
。
注意,在 C或java :替换 for (i=0; i<M; ++i)
代替 for i in range(M):
。
替换 for (j=p; j<k-1; ++j)
代替 for j in range(p,k-1):
。
正确性:请注意M = x
框被选中,因为 print "x",
执行M
次。
答案 5 :(得分:0)
如何使用Fisher–Yates shuffle?
制作数组,随机播放并选择前n个元素。你不需要将它们全部洗牌,只需要数组的前n个。在大多数语言库中都可以找到改组。