使用百分比时,查找创建另一个整数的随机整数

时间:2013-09-13 03:31:56

标签: java math

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

我对这个令人困惑的标题感到抱歉,让我澄清一下我的问题:

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

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

25% of 4616 = ?

要求是:

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

有没有快速方法可以找到满足最后要求的随机数?

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

但是这个循环可以运行数千次,直到找到正确的数字。

我的问题有更好的方法吗?

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

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

  

7620的65%=?

因为解4953也是整数。

我想找到一个介于100和9999之间的随机数,它是一个整数,并且在方程p * x = y中有一个整数。

4 个答案:

答案 0 :(得分:1)

我只需选择一个百分比并从答案中向后工作即可得出问题:

p * x = answer | 0 < p < 100, p = 5k, 100 <= x < 10000

所以,选择你的百分比:

p = (5 * rand(1, 9)) / 100.0;

确保您的100 <= answer / p < 10000

answer = rand(100, p * 9999);

解决'未知':

x = p / y

答案 1 :(得分:1)

你是对的,分隔符取决于p值。因此,首先选择p,然后使用它来计算分隔符以选择范围内的随机数:

For 5% it should be dividable by 20 (5/100 = 1/20)
For 10% it should be dividable by 10 (10/100 = 1/10)
For 15% it should be dividable by 20 (15/100 = 3/20)
For 20% it should be dividable by 5 (20/100 = 1/5)
For 25% it should be dividable by 4 (25/100 = 1/4)
For 30% it should be dividable by 10 (30/100 = 3/10)
...

您可以通过减少分数p/100并选择分母

来计算它

以下答案不正确

看起来你必须从100-9999范围内选择可以分割20的数字。

answer = x * p/100 = x * k/20 (since p is dividable by 5)
k = rand(1,494)
x = 100 + 20*k
p = 5*rand(1,20)

答案 2 :(得分:1)

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

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

对于x,我们的约束为100 <= x <= 999

首先选择满足a的{​​{1}}。

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

20 | (a * 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) 小于20,因此它的素数分解可能非常简单并且可能与素数分解“重叠”。例如,如果a,则上述等式简化为

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) = ka/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,但情况并非总是如此。

答案 3 :(得分:0)

好的,感谢roliu我终于找到了解决方案。 这是我的最终解决方案的样子:

创建1到20之间的随机数(因为百分比可以按5分割):

a = rand(1,20)

找出最大公约数:

b = gcd(a,20)

创建一个范围除以20 / gcd的随机数(如果您不知道原因,请参见denis答案):

c = rand(floor(100/(20/b)),floor(9999/(20/b)))

将随机数乘以20 / gcd得到范围内的数字,我们的x:

x = floor(c * (20/b))

将数字乘以百分比以获得解决方案y:

y = floor(x * (a/20))

将百分比转换为要打印的正确值:

p = a * 5

最终等式:

p % of x = y