【数论】法雷数列

实数包含有理数和无理数,任何有理数都可以表示为p/q(p,q是整数,q!=0)的形式,如果指定一个分数的分母不超过某个值,对于一般的有理数或者无理数,是不可以用一个分数来准确地表示的。我们这里主要讨论,如何找出一对分数 p1/q1和p2/q2,使得q1 和q2 小于给定的值n,而p1/q1和p2/q2尽可能接近一个给定的实数.。

        先给出一些定义和一个定理:

定义一: 最简分数(也称既约分数或不可约分数)。若p,q的最大公约数是1,我们称分数p/q

              是最简分数。

定义二: 真分数,若p,q是正整数,0<p/q<1, 我们说p/q是真分数

定理:                                                                              


             分数a/b, c/d是最简真分数(也可以是0/1或者1/1)且a/b <c/d, 则有                                      

              1)  数(a+c)/(b+d)是一个最简分数     

              2)  a/b < (a+c)/(b+d) < c/d


      证明略
法雷数列: 对任意给定的一个自然数n,将分母小于等于n的不可约的真分数按升序排
                  列,并且在第一个分数之前加上0/1,在最后一个分数之后加上1/1,这个
                  序列称为n级法雷数列,以Fn表示。
                  如F5为:1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5.
法雷数列的构造:应用定理中的(2),如果 a/b 和 c/d 是一个法雷数列,则在它们中间可以
                   插入 (a+c)/(b+d),所以可以二分构造,直到不能构造为止
                   比如 N = 5:

             step1: 准备两个数 0/1, 1/1 作为整个法雷数列的第一个元素和最后一个元素
                              0/1, 1/1
                   step2: 在两个数中间插入1个数1/2, 变为
                              0/1, 1/2, 1/1
                   step3: 在每对相邻两个数中间插入1个数,变为
                              0/1, 1/3, 1/2, 2/3, 1/1
                   step4: 在每对相邻两个数中间插入1个数,变为
                              0/1, 1/4, 1/3, 2/5 , 1/2, 3/5, 2/3, 3/4 , 1/1
                   step5: 0/1 和 1/4 之间 和3/4和 1/1 仍然可插入1个数,且插入的数分母不大于5
                              0/1, 1/5 , 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5 , 1/1
                   至此,该序列包含了所有分母不大于5的最简真分数,且各个分数以递增顺序排 列。


附递归构造法雷数列的程序:
01.#include <cstdio>  
02.#include <cstring>  
03.using namespace std;  
04.int N;  
05.void farey(int a,int b,int c,int d){  
06.    if(b+d > N) return ;  
07.    if(b+d == N){  
08.        printf("%d/%d",a+c,b+d);  
09.        if(a+c != N-1) printf(",");  
10.        return ;  
11.    }  
12.    farey(a,b,a+c,b+d);  
13.    printf("%d/%d,",a+c,b+d);  
14.    farey(a+c,b+d,c,d);  
15.}  
16.int main()  
17.{  
18.    int T;  
19.    scanf("%d",&T);  
20.    while(T--){  
21.        scanf("%d",&N);  
22.        farey(0,1,1,1);  
23.        printf("/n");  
24.    }  
25.} 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值