Algorithm 查找具有属性的有理数
我必须写一个程序来找到一个有属性的有理数。我写了代码来检查属性,但是现在我不知道如何检查所有的有理数。我试过了Algorithm 查找具有属性的有理数,algorithm,rational-numbers,Algorithm,Rational Numbers,我必须写一个程序来找到一个有属性的有理数。我写了代码来检查属性,但是现在我不知道如何检查所有的有理数。我试过了 float rat; for (int i=1 ; i ; ++i) { for (int j=1 ; j ; ++j) { rat = (float)i/(float)j; if goodRat(rat) then return rat; } } 但它永远不会结束!它错过了太多。然后我试了这个 float rat; while { int i = ran
float rat;
for (int i=1 ; i ; ++i) {
for (int j=1 ; j ; ++j) {
rat = (float)i/(float)j;
if goodRat(rat) then return rat;
}
}
但它永远不会结束!它错过了太多。然后我试了这个
float rat;
while {
int i = random(1000) + 1;
int j = random(1000) + 1;
rat = (float)i/(float)j;
if goodRat(rat)
return rat;
}
但这只在某些时候起作用。我怎样才能解决这个问题呢?这是一种系统地生成所有理性而不重复的方法。参见。上的其他部分。有理数是可数的,这意味着它们可以与整数一一对应。如果你这样做,你就会有你的解决方案
与给出一对一的对应关系不同,下面是一种更容易理解理性的方法
通过(可数)无限矩阵Q
构造一个(可数)无限矩阵Q(i,j)=i/j
,其中i
和j
的范围从1
到无限。矩阵如下所示:
1 1/2 1/3 1/4 1/5 . . .
2/1 2/2 2/3 2/4 2/5 . . .
3/1 3/2 3/3 3/4 3/5 . . .
4/1 4/2 4/3 4/4 4/5 . . .
5/1 5/2 5/3 5/4 5/5 . . .
. . . . .
. . . . .
. . . . .
当然,有很多重复(整个对角线是1!),但我要简单而不是快速
你要做的是沿着无限的列走,这样你会错过很多数字。相反,你应该沿着反对角线走,这是有限的。也就是说,按以下顺序获取元素
1 3 6 10 15 .
2 5 9 14 . .
4 8 13 . . .
7 12 . . .
11 . . .
. . .
. .
.
所以你会得到1,2/1,1/2,3/1,2/2,1/3,4/1,3/2,2/3,1/4,
。此外,您知道您将在步骤(r+s)(r+s-1)/2+s中遇到r/s
,因此任何给定的有理数都将在有限时间内遇到
对其进行编码的一种方法是将i
作为行索引(外部for
loop),将j
作为列索引(内部for
loop)。然后,i
的范围是从1
到无限
,但j
的范围仅是从1
到i
如果你的goodRat
函数需要相当长的时间,那么你可以先测试i
和j
是互质函数,如果不跳过它们,就可以加快速度。首先,关于你的第一次尝试:
float rat;
for (int i=1 ; i ; ++i) {
// the loop for the first won't be reached
for (int j=1 ; j ; ++j) {
// this loop will never end, it will either loop for ever or return something like (floag)1/(float)j
rat = (float)i/(float)j;
if goodRat(rat) then return rat;
}
}
我的建议是,明确你的目的,也许你可以参考一下,当你把它转换成浮点数时,它不再是一个“理性”数。根据定义,有理数表示两个整数的比率。您需要告诉我们goodRat()的作用。检查大量的理性可能是必要的,也可能不是必要的。如果你不告诉我们目标是什么,我们就无法判断是否有更好的方法。更不用说……在任意两个之间存在无限多的有理数,所以我认为你需要定义你想要更多检查的约束precisely@Ollie:所有浮点值都是有理数。当然,并非所有的有理数都可以表示为浮点数,(float)i/float(j)
通常并不完全等于i
和j
的真实比率@kaveman:这是不相关的。它们仍然是可数的。我只是在浏览你的一些答案,你的数学/数论背景让我困惑!引用当时的话:“简单的测试i和j是互质的”,你就完成了。甜蜜的