解决了,关于我的问题的精确解决方案,请参阅我的答案

抱歉,标题令人困惑,让我澄清一下我的问题:

我的Java程序应该问一个带有百分比的数学问题。

它应该以这种格式创建一个问题:

25% of 4616 = ?


要求是:


百分比总是可以除以5(没问题)
该数字(此处为4616)必须介于100和9999之间(这也不是问题)
数字以及结果必须是整数(这是我的问题)


有没有一种快速的方法来找到满足最后要求的随机数?

我能想到的唯一解决方案是找到百分比,然后创建一个循环,直到找到满足要求的随机数(在本例中,直到number % 4 == 0为真),该循环才会停止

但是,此循环可能会运行数千次,直到找到正确的数字为止。

有没有更好的方法解决我的问题?

编辑:
似乎我没有弄清楚我的问题是什么,我不希望结果是双数,而只是整数。

例如:如果我的百分比是65%,那么可能的问题是


  7620的65%=?


因为解决方案4953也是整数。

我想找到一个介于100和9999之间的随机数,它是一个整数,并具有一个整数,作为等式p * x = y的结果。

最佳答案

p为百分比(分子,即25%),x为初始值,y为结果整数。

由于p是5的倍数且是0 to 100的百分比,因此我们可以将其表示为p = 5a/100 = a/20其中0 <= a <= 20

对于x,我们具有100 <= x <= 999的约束。

首先选择一个满足a0 <= a <= 20

接下来,我们选择一个x。好吧,要使p * x = (a/20) * x是整数结果,我们只需要20除以a * x。好吧,我们知道20 | (a * x)(“ 20除以* x”)仅当且仅当

j = (a * x) / 20 (<- j is some integer)
<=> j = (a * x) / (2^2 * 5^1)


既然有了a,我们可以用它的素因数分解来代替它:

j = (p1^e1 * p2^e2 * ... * pn^en) * x / (2^2 * 5^1)


现在意识到a小于20,因此其素因数分解可能非常简单,并且可能与素因数分解“重叠”。例如,如果a = 5,则上述方程式简化为

j = x / 4


在这种情况下,很容易看出我们如何生成将生成整数x(4的倍数)的j。尽管您也需要100 <= x <= 9999!因此,“重叠”(即分子中的质数与分母相同)是超级有益的。那就是最大的除数起作用的地方。 GCD(a, 20)是除a20的最大整数。 GCD的素数分解恰好是重叠。它还具有不错的属性,即一旦我们“去除”了重叠部分,结果值将变为:

j = b * x / c


具有bc是互质的好属性。从中我们知道b * x / c是且仅当c | x时是整数。

因此,让GCD(a, 20) = k。然后根据定义,我们有a/k = b20/k = c,所以有a/20 = b/c。因此,让x = c * m其中m是整数。然后我们有:

100 <= m * c <= 9999
=> 100 / c <= m <= 9999 / c


因此,我们可以执行floor(rand(100 / c, 9999 / c))来生成您的m

总结一下:

a = rand(0, 20)
p = 5*a
c = 20 / GCD(a, 20)
m = floor(rand(100 / c, 9999 / c))
x = c * m
y = (p / 100) * x


请注意,a = 0实际上是边缘情况,此外,floor()不会给您完全均匀的分布。如果您需要覆盖这些内容,我可能会考虑一下并稍作调整。另外,欧几里得算法的实现很简单,您可以查找一下。哎呀,由于a < 20,您可能只需对函数进行硬编码即可:)

编辑我第一次忘记在摘要中定义c。这是一个产生下面的反例的例子:

a = 5
p = 25
c = 20 / GCD(5, 20) = 20 / 5 = 4
m = some integer in [25, 2500). In this case so we randomed 879
x = 3516
y = 879


方便地,在此示例中,我们有GCD(a, 20) = 5,因此事实证明m = y,但并非总是如此。

10-07 12:57
查看更多