解决了,关于我的问题的精确解决方案,请参阅我的答案
抱歉,标题令人困惑,让我澄清一下我的问题:
我的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
的约束。
首先选择一个满足a
的0 <= 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)
是除a
和20
的最大整数。 GCD
的素数分解恰好是重叠。它还具有不错的属性,即一旦我们“去除”了重叠部分,结果值将变为:j = b * x / c
具有
b
和c
是互质的好属性。从中我们知道b * x / c
是且仅当c | x
时是整数。因此,让
GCD(a, 20) = k
。然后根据定义,我们有a/k = b
和20/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
,但并非总是如此。