简体   繁体   English

在 Java 中查找分数的出现次数

[英]Finding # of occurrences of fractions in Java

I am trying to find and print the number of occurrences of fractions from a file in my program.我正在尝试从我的程序中的文件中查找并打印分数的出现次数。 Fractions that simplify down to the same number counts as an occurrence, so 12/6 counts for 6/3 as well.简化为相同数字的分数算作一次出现,因此 12/6 也算作 6/3。 So far, I have separated the fractions into numerator and denominator in separate arrays.到目前为止,我已将分数分成单独的 arrays 中的分子和分母。 The fractions I have in the numerator and denominator came from a separate array that I received from a file.我在分子和分母中的分数来自我从文件中收到的一个单独的数组。 I am having trouble trying to figure out how to simplify the fractions and also find the total occurrence of them.我无法弄清楚如何简化分数并找到它们的总出现次数。 This is what I have so far:这是我到目前为止所拥有的:

String[] split = new String[2]; //String that holds numerator and denominator
    int[] numerator = new int[100];
    int[] denominator = new int[100];

    for(int i = 0; i < numOfFractions; ++i) { //Loop through # of Lines
        split = fractions[i].split("/");  //Split the fractions at the /
        System.out.println("Test here " + fractions[i]);  //TODO --> test
        numerator[i] = Integer.parseInt(split[0]);  //Numerator
        System.out.println("Numerator = " + numerator[i]);  //TODO --> test
        denominator[i] = Integer.parseInt(split[1]);  //Denominator
        System.out.println("Denominator = " + denominator[i] + "\n");    //TODO --> test
    }

}

I have added some tests within my method to make sure everything is working properly, which it seems so far it is.我在我的方法中添加了一些测试,以确保一切正常,到目前为止似乎是这样。

These are the fractions obtained from a file.这些是从文件中获得的分数。 Each fraction is on its own line, and can assume every fraction will be (A/B) format 6/3 4/2 5/9 80/90 800/900 15/25 5/5 1/1 1/10 1/100 1/1000 1/3 2/6 1/2 1/3 1/1 1/4 1/5 1/6 1/7 1/8 1/9 2/1 2/2 2/3 2/4 2/5 2/6 2/7 2/8 2/9每个分数都在自己的行上,并且可以假设每个分数都是 (A/B) 格式 6/3 4/2 5/9 80/90 800/900 15/25 5/5 1/1 1/10 1/ 100 1/1000 1/3 2/6 1/2 1/3 1/1 1/4 1/5 1/6 1/7 1/8 1/9 2/1 2/2 2/3 2/4 2 /5 2/6 2/7 2/8 2/9

You can reduce them by finding the greatest common divisor of the numerator and the denominator.您可以通过找到分子和分母的最大公约数来减少它们。 You can do it like so.你可以这样做。

public static int gcd(int r, int s) {
    while (s > 0) {
        int t = r % s;
        r = s;
        s = t;
    }
    return r;
}

for 27/12 27/12

int d = gcd(27,12); // returns 3

27/3 = 9
12/3 = 4

so the reduced fraction is 9/4 .所以减少的分数是9/4 So every equal fraction will reduce to the same value when the numerator and denominator are divided by the GCD of those numbers.因此,当分子和分母除以这些数字的 GCD 时,每个相等的分数都会减小到相同的值。

It uses Euclid's Algorithm它使用欧几里得算法

Here is how it might be applied in your case.以下是它在您的案例中的应用方式。

  • create a map to hold the reduced fraction as key and a list of the original form of that fraction.创建一个 map 来保存减少的分数作为键和该分数的原始形式的列表。
  • then convert the fraction to a numeric value and divide by the GCD然后将分数转换为数值并除以 GCD
  • then store the reduced fraction as a string and add the original fraction to the list然后将减少的分数存储为字符串并将原始分数添加到列表中
Map<String, List<String>> fractions = new HashMap<>();
    
String[] s = {"10/2", "27/3", "19/4",  "15/3", "12/4",  "3/5", "9/15"};
    
for (String v : s) {
    String[] nd = v.split("/");
    int n = Integer.parseInt(nd[0]);
    int d = Integer.parseInt(nd[1]);
    int div = gcd(n,d);
    n /= div;
    d /= div;
    String reduced = String.format("%d/%d", n,d);
    fractions.computeIfAbsent(reduced, k->new ArrayList<>()).add(v); 
}
    
fractions.entrySet().forEach(System.out::println);
}

prints印刷

3/1=[12/4]
5/1=[10/2, 15/3]
3/5=[3/5, 9/15]
19/4=[19/4]
9/1=[27/3]

I would create a Fraction class as below.我将创建一个分数 class 如下。 I would override equals() and hashCode() methods, so I can use this class with Map.我将覆盖 equals() 和 hashCode() 方法,因此我可以将此 class 与 Map 一起使用。

public class Fraction {
    int nominator;
    int denominator;

    public Fraction(int nominator, int denominator) {
        this.nominator = nominator;
        this.denominator = denominator;
    }
    
    /**
     * The method checks if two fractions are equal. 
     * Example 1: Fraction 1 is 5/3 and Fraction 2 is 7/4.
     * The method checks if 5X4 == 7X3 and returns false.
     * Example 2: Fraction 1 is 12/6 and Fraction 2 is 8/4.
     * The method checks 12X4 == 8X6 and returns true.
     * @param obj
     * @return 
     */
    @Override
    public boolean equals(Object obj){
        if(obj.getClass() != this.getClass()){
            return false;
        }
        Fraction f = (Fraction)obj;
        int nominator1 = this.getNominator();
        int nominator2 = f.getNominator();
        int denominator1 = this.getDenominator();
        int denominator2 = this.getDenominator();
        nominator1 = nominator1 * denominator2;
        nominator2 = nominator2 * denominator1;
        return nominator1 == nominator2;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 97 * hash + this.nominator;
        hash = 97 * hash + this.denominator;
        return hash;
    }

    public int getNominator() {
        return nominator;
    }

    public int getDenominator() {
        return denominator;
    } 
}

Then, I would create Fraction objects from your data input file.然后,我将从您的数据输入文件中创建 Fraction 对象。 I understand you already have retrieved integer values of nominators and denominators.我了解您已经检索到了提名者和分母的 integer 值。 The following code creates a new Fraction object and adds it into the list.以下代码创建一个新的分数 object 并将其添加到列表中。

List<Fraction> fractions = new ArrayList<>();
Fraction fr = new Fraction(1, 2); 
fractions.add(fr);

Once you populate the list with your input data, you can use a Map to find and print the result.使用输入数据填充列表后,您可以使用 Map 查找并打印结果。

Map<Fraction,Integer> map = new HashMap<>();
       for(Fraction f: fractions){
           if(map.containsKey(f)){
               int value = map.get(f);
               value++;
               map.put(f, value);
           } else {
               map.put(f, 1);
           }
       }
       
       System.out.println(map);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM