📜  生成正有理数的算法

📅  最后修改于: 2021-04-29 01:10:37             🧑  作者: Mango

有理数的形式为p / q,其中p和q是整数。问题陈述是生成有理数,以便在有限的时间内生成任何特定的数。对于给定的n,我们生成所有有理数,其中1 <= p <= n和1 <= q <= n

例子:

Input : 5
Output : 1, 1/2, 2, 1/3, 2/3, 3/2, 3, 1/4,
         3/4, 4/3, 4, 1/5, 2/5, 3/5, 4/5,
         5/4, 5/3, 5/2, 5

Input : 7
Output :1, 1/2, 2, 1/3, 2/3, 3/2, 3, 1/4, 3/4,
        4/3, 4, 1/5, 2/5, 3/5, 4/5, 5/4, 5/3, 
        5/2, 5, 1/6, 5/6, 6/5, 6, 1/7, 2/7, 3/7,
        4/7, 5/7, 6/7, 7/6, 7/5, 7/4, 7/3, 7/2, 7

用数学术语来说,如果一个集合的元素可以与一组自然数一一对应,则它是无穷大的。

这里的问题陈述是生成p / q的组合,其中p和q都是整数,并且p和q的任何特定组合都将以有限的n达到。步骤。如果将p递增1、2、3…等,使q保持恒定,反之亦然,则不能在有限时间内达到所有组合。处理此问题的方法是想象自然数以矩阵col的形式排列成一行

(1、1)(1、2)(1、3)(1、4)
(2,1)(2,2)(2,3)(2,4)
(3,1)(3,2)(3,3)(3,4)
(4,1)(4,2)(4,3)(4,4)

这些元素在每次迭代中以倒L形遍历

(1,1)
(1,2),(2,2)(2,1)
(1、3),(2、3),(3、3),(3、2),(3、1)

屈服

1/1
1 / 2、2 / 2、2 / 1
1 / 3、2 / 3、3 / 3、3 / 2、3 / 1

显然,这将产生2/1和4/2等重复项,但是可以使用最大公因数约束将其删除。

// Java program 
import java.util.ArrayList;
import java.util.List;
  
class Rational {
  
    private static class RationalNumber {
  
        private int numerator;
        private int denominator;
  
        public RationalNumber(int numerator, int denominator)
        {
            this.numerator = numerator;
            this.denominator = denominator;
        }
  
        @Override
        public String toString()
        {
            if (denominator == 1) {
                return Integer.toString(numerator);
            }
            else {
                return Integer.toString(numerator) + '/' + 
                       Integer.toString(denominator);
            }
        }
    }
  
    /**
     * Greatest common divisor
     * @param num1
     * @param num2
     * @return
     */
    private static int gcd(int num1, int num2)
    {
        int n1 = num1;
        int n2 = num2;
  
        while (n1 != n2) {
            if (n1 > n2)
                n1 -= n2;
            else
                n2 -= n1;
        }
        return n1;
    }
  
    private static List generate(int n)
    {
  
        List list = new ArrayList<>();
  
        if (n > 1) {
            RationalNumber rational = new RationalNumber(1, 1);
            list.add(rational);
        }
  
        for (int loop = 1; loop <= n; loop++) {
  
            int jump = 1;
  
            // Handle even case
            if (loop % 2 == 0)
                jump = 2;
            else
                jump = 1;
  
            for (int row = 1; row <= loop - 1; row += jump) {
  
                // Add only if there are no common divisors other than 1
                if (gcd(row, loop) == 1) {
                    RationalNumber rational = new RationalNumber(row, loop);
                    list.add(rational);
                }
            }
  
            for (int col = loop - 1; col >= 1; col -= jump) {
  
                // Add only if there are no common divisors other than 1
                if (gcd(col, loop) == 1) {
                    RationalNumber rational = new RationalNumber(loop, col);
                    list.add(rational);
                }
            }
        }
  
        return list;
    }
  
    public static void main(String[] args)
    {
        List rationals = generate(7);
        System.out.println(rationals.stream().
                  map(RationalNumber::toString).
                  reduce((x, y) -> x + ", " + y).get());
    }
}
输出:
1, 1/2, 2, 1/3, 2/3, 3/2, 3, 1/4, 3/4, 4/3, 4, 1/5, 2/5, 3/5, 4/5, 5/4, 5/3, 5/2, 5, 1/6, 5/6, 6/5, 6, 1/7, 2/7, 3/7, 4/7, 5/7, 6/7, 7/6, 7/5, 7/4, 7/3, 7/2, 7