Java生成正有理数算法


有理数 - 可以表示为p/q形式的数,其中p和q都是整数,且q不等于0。

正有理数是指最终值为正数的有理数。为此,p和q必须都为正数或都为负数。

本问题旨在生成不超过给定数字n的正随机数。我们需要生成有限数量的正有理数到n,即我们将在1到n之间找到有理数。对于此算法,我们将生成随机数,其中1 <= p <= n且1 <= q <= n。

让我们举个例子来更好地阐述这个概念:

Input : 3
Output : 1, ½ , ⅓ , 2 , ⅔ , 3/2 , 3 .

说明 - 在此示例中,我们将考虑p和q的值在1到3之间。

为此设计的算法将使用集合,集合是生成所需组合的最佳数据结构。因为集合可以映射,并且映射可以是n到n的顺序,即集合1中的每个值都可以与集合2中的值正确映射,从而创建可以生成所需对的映射。为了生成所需的对,我们将使用两个正值集合并将这些值映射以获得解。

让我们举个例子:

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

让我们使用反向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

虽然存在像1∕1、2∕2、3∕3这样的指向相同值的值。我们将使用最大公约数消除这些值。

示例

import java.util.ArrayList;
import java.util.List;
class PositiveRational {
   private static class PositiveRationalNumber {
      private int numerator;
      private int denominator;
      public PositiveRationalNumber(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);
         }
      }
   }
   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<PositiveRationalNumber> generate(int n){
      List<PositiveRationalNumber> list = new ArrayList<>();
      if (n > 1) {
         PositiveRationalNumber rational = new PositiveRationalNumber(1, 1);
         list.add(rational);
      }
      for (int loop = 1; loop <= n; loop++) {
         int jump = 1;
         if (loop % 2 == 0)
            jump = 2;
         else
            jump = 1;
         for (int row = 1; row <= loop - 1; row += jump) {
            if (gcd(row, loop) == 1) {
               PositiveRationalNumber rational = new PositiveRationalNumber(row, loop);
               list.add(rational);
            }
         }
         for (int col = loop - 1; col >= 1; col -= jump) {
            if (gcd(col, loop) == 1) {
               PositiveRationalNumber rational = new PositiveRationalNumber(loop, col);
               list.add(rational);
            }
         }
      }
      return list;
   }
   public static void main(String[] args){
      List<PositiveRationalNumber>rationals = generate(5);
      System.out.println(rationals.stream().
      map(PositiveRationalNumber::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

更新于:2019年10月16日

715 次浏览

开启您的职业生涯

完成课程获得认证

开始学习
广告