Java分数计数器与类

时间:2015-04-15 17:06:35

标签: java arrays counter

由于某种原因,我非常困难。我有一个程序从输入文件中读取分数,将每一行分配给一个字符串,然后将内容保存到类Fraction(分子和分母)。然后将fraction对象保存到名为fractionList的数组中。

我有另一个类FractionCounter,它以简化形式计算分数的出现次数,如果有任何重复,则程序将简单地添加到该对象的整数“计数器”。 FractionCounter个对象存储在名为fracCount的对象列表中。

我的问题是当我将对象添加到fracCount FractionCounter个对象列表时。我正在使用分支语句来确定是否应该添加一个新的分数元素(一个与数组fracCount中其他分数的任何缩减形式都不匹配的元素)到fracCount,或者如果我应该在共享相同的降低分数值的元素中为counter变量添加一个值。

除非我试图确定派系对象是否是副本,否则一切正常。使用我的代码,我的fracCount数组为空。

这是我的代码

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);
                        }
                    }
                }
            }   
        }
    }
}

3 个答案:

答案 0 :(得分:4)

有一种非常自然的方法可以检查两个简单的分数是否相等而不将它们转换为浮点数。

如果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;
}

答案 1 :(得分:1)

问题是你要划分整数?

  numerator/denominator

当你将 4/6 1/7 分开时会发生什么?有了整数,它们都会产生0,所以你会得到意想不到的平等。

您可以转换为双重

  (double)numerator/(double)demoninator

但请记住,相等的浮点比较并不明显,通常我们测试

 if ( ( oneDouble - anotherDouble ) < someTinyValue )

答案 2 :(得分:0)

我认为这是给你带来问题的一句话(.equals方法Fraction

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

它当前正在执行整数除法,因此1/2 == 0和1/3 == 0,因此您的代码会将每个分数视为已经存在于分数列表中。

您希望使用某种epsilon执行浮点运算。

Why Are Floating Point Numbers Inaccurate?