【问题标题】:Java fraction counter with classes带类的 Java 分数计数器
【发布时间】:2015-04-15 17:06:34
【问题描述】:

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

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

我的问题是当我将一个对象添加到FractionCounter 对象的fracCount 列表时。我正在使用分支语句来确定是否应该向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);
                        }
                    }
                }
            }   
        }
    }
}

【问题讨论】:

    标签: java arrays counter


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      是你划分整数的问题吗?

        numerator/denominator
      

      当你分开 4/61/7 时会发生什么?对于整数,它们都会产生 0,所以你会得到一个意想不到的相等。

      你可以转换成双精度

        (double)numerator/(double)demoninator
      

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

       if ( ( oneDouble - anotherDouble ) < someTinyValue )
      

      【讨论】:

        【解决方案3】:

        我认为这是给您带来问题的行(在Fraction.equals 方法中:

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

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

        您需要使用某种 epsilon 执行浮点运算。

        Why Are Floating Point Numbers Inaccurate?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-25
          相关资源
          最近更新 更多