简体   繁体   English

Java分数计数器与类

[英]Java fraction counter with classes

I am very stuck on an assignment for some reason. 由于某种原因,我非常执着于作业。 I have a program that reads fractions from an input file, assigns each line to a string, and then saves the contents to the class Fraction (numerator and denominator). 我有一个程序从输入文件中读取分数,将每一行分配给一个字符串,然后将内容保存到Fraction类(分子和分母)中。 The fraction object is then saved into an array called fractionList . 然后将分数对象保存到一个名为fractionList的数组中。

I have another class FractionCounter that counts the occurrences of fractions in their reduced form, and if there are any repeats then the program will simply add to the integer "counter" of that object. 我还有另一个类FractionCounter ,它以简化形式计算FractionCounter的出现,如果有重复,则程序将简单地添加到该对象的整数“ counter”中。 The FractionCounter objects are stored in an object list called fracCount . FractionCounter对象存储在名为fracCount的对象列表中。

My problem is when I am adding an object to the fracCount list of FractionCounter objects. 我的问题是将对象添加到FractionCounter对象的fracCount列表时。 I am using a branching statement to determine whether I should add a new fraction element (one that doesn't match any of the reduced form of the other fractions in the array fracCount ) to fracCount , or if I should add a value to the counter variable in an element that shares the same reduced fraction value. 我使用的分支语句来确定我是否应该添加一个新的分数元件(一个不匹配任何在阵列的其它馏分的还原形式的fracCount )至fracCount ,或者如果我应的值添加到counter共享相同减少分数值的元素中的变量。

Everything works except when I am trying to determine whether the faction object is a copy or not. 一切正常,除非我尝试确定派系对象是否为副本。 With the code I have, my fracCount array is empty. 使用我拥有的代码,我的fracCount数组为空。

Here is my code 这是我的代码

public class Fraction {
    private int numerator;
    private int denominator;

    Fraction(){ // default, no arg constructor
    }
    // constructor that initializes data
    Fraction(int numerator, int denominator){
        this.numerator = numerator;
        if(denominator > 1000){
            this.denominator = 1;
        }else if(numerator == denominator){
            this.numerator = 1;
            this.denominator = 1;
        }else if(denominator == 0){
            System.out.println("Zero is not a valid denominator");
        }else{
            this.denominator = denominator;
        }
    }
    // compares this fraction object to 'other' fraction object
    boolean equals(Fraction other){
        if(this.numerator == other.numerator && 
                this.denominator == other.denominator){
            return true;
        }else if((this.numerator / this.denominator) ==
                (other.numerator / other.denominator)){
            return true;
        }else{
            return false;
        }
    }
    // gives user access to the numerator and denominator
    public int getNumerator(){
        return this.numerator;
    }
    public int getDenominator(){
        return this.denominator;
    }   
}

public class FractionCounter extends Fraction{
    private Fraction theFraction;
    private int counter = 1;

    FractionCounter(Fraction theFraction){
        this.theFraction = theFraction;
    }
    public boolean compareAndIncrement(Fraction newFraction){
        if((theFraction.getNumerator() / theFraction.getDenominator() == 
                newFraction.getNumerator() / newFraction.getDenominator())){
            this.counter++;
            return true;
        }else if(theFraction.getDenominator() == 0 || 
                newFraction.getDenominator() == 0){
            return false;
        }else{
            return false;
        }
    }
}

public class ObjectList {
    private int N;
    private Fraction[] fractionList;
    private int numElements = 0;

    public ObjectList(int n){
        this.N = n;
        this.fractionList = new Fraction[N];
    }
    public void add(Fraction next){
        fractionList[numElements] = next;
        numElements++;
    }
    public int size(){
        return this.numElements;
    }
    public Fraction getFraction(int i){
        return fractionList[i];
    }
}

    import java.util.Scanner;
    import java.awt.List;
    import java.io.*;
    import java.util.Arrays;

    public class FractionDriver {
    public static void main(String[] args){

        // creates scanner object
        Scanner fractions = null;

        // uses scanner to import fractions file and read how many lines 
        try{
            fractions = new Scanner(new FileInputStream("fractions.txt"));
        }catch(FileNotFoundException e){
            System.out.println("Cannot find fractions.txt");
            System.exit(0);
        }

        // creates a large array that stores the text file
        String[] input = new String[100];

        int numLines = 0; // counts the number of fractions
        int numElement = 0; // counts the current index element
        while(fractions.hasNextLine()){
            input[numElement] = fractions.next();
            numElement++;
            numLines++;
        }
        fractions.close(); // closes the input stream

        // create object list of fractions
        ObjectList fractionList = new ObjectList(numLines);
        ObjectList fractCount = new ObjectList(numLines);

        int totalFractions = 0;

        for(int i = 0; i < numLines; i++){

            totalFractions++; // adds one on every new line

            // creates an array for each fraction where frac[0] is the 
            // numerator and frac[1] is the denominator
            String[] fract = input[i].split("/"); 

            // converts the string values to integers
            int numerator = Integer.parseInt(fract[0]);
            int denom = Integer.parseInt(fract[1]);

            // creates a fraction object and assigns instance variables
            Fraction f = new Fraction(numerator, denom);
            FractionCounter count = new FractionCounter(f);

            // adds the fraction to the array if the denominator
            // is not zero
            if(f.getDenominator() != 0){
                fractionList.add(f);
                for(int j = 0; j < totalFractions; j++){
                    if(fractCount.getFraction(j) != null){
                        if(!f.equals(fractCount.getFraction(j))){
                            fractCount.add(count);
                        }else{
                            count.compareAndIncrement(f);
                        }
                    }
                }
            }   
        }
    }
}

There is a very natural way to check if two simple fractions are equal by value without converting them to floating-point numbers. 有一种非常自然的方法来检查两个简单的分数是否等于值,而无需将它们转换为浮点数。

If a/b = c/d , then ad = bc (except for b or d = 0), so: 如果a/b = c/d ,则ad = bcbd = 0除外),因此:

boolean equals(Fraction other) {
    if (this.denominator == 0 || other.denominator == 0)
         return false; // undefined
    return this.numerator * other.denominator == other.numerator * this.denominator;
}

Is the problem that you are dividing ints? 您正在分割整数的问题吗?

  numerator/denominator

What happens when you divide say, 4/6 and 1/7 ? 当您说4/61/7时会发生什么? With ints they will both yield 0 so you get an unexpected equality. 使用int时,它们都将产生0,因此您将获得意外的相等性。

You can convert to double 您可以转换成双倍

  (double)numerator/(double)demoninator

but remember that floating point comparison for equality is not obvious, usually we test 但是请记住,对于相等性而言,浮点比较并不明显,通常我们会进行测试

 if ( ( oneDouble - anotherDouble ) < someTinyValue )

I think this is the line that is giving you problems (in the .equals method of Fraction : 我认为这是给您带来麻烦的.equals行(在Fraction.equals方法中:

 (this.numerator / this.denominator) == (other.numerator / other.denominator)

It is currently performing integer division, so 1/2 == 0 and 1/3 == 0, so your code considers EVERY fraction to already be in the list of fractions. 它当前正在执行整数除法,因此1/2 == 0和1/3 == 0,因此您的代码认为每个分数都已经在分数列表中。

You'll want to perform floating point arithmetic with some sort of epsilon. 您将要使用某种epsilon执行浮点运算。

Why Are Floating Point Numbers Inaccurate? 为什么浮点数不正确?

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

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