2015-04-15 3 views
2

Я очень зациклен на задании по какой-то причине. У меня есть программа, которая считывает фракции из входного файла, назначает каждую строку строке, а затем сохраняет содержимое в класс Fraction (числитель и знаменатель). Затем объект фракции сохраняется в массив с именем fractionList.Счетчик фракций Java с классами

У меня есть еще один класс FractionCounter, который учитывает вхождения дробей в их приведенную форму, а если есть какие-либо повторы, то программа просто добавит к целочисленному «счетчику» этого объекта. Объекты FractionCounter хранятся в списке объектов, который называется fracCount.

Моя проблема в том, что когда я добавляю объект в список fracCountFractionCounter объектов. Я использую оператор ветвления, чтобы определить, должен ли я добавить новый элемент фракции (тот, который не соответствует ни одной из приведенных форм других дробей в массиве 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); 
         } 
        } 
       } 
      } 
     } 
    } 
} 

ответ

4

Существует очень естественный способ, чтобы проверить, если две простые дроби равны по значению без их преобразования чисел с плавающей точкой.

Если a/b = c/d, то ad = bc, так (для b или d = 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

Есть проблема, что вы разделяете Интс?

numerator/denominator 

Что происходит, когда вы делите сказать, 4/6 и 1/7? С ints они оба дадут 0, чтобы получить неожиданное равенство.

Вы можете конвертировать в два раза

(double)numerator/(double)demoninator 

, но помните, что сравнение с плавающей точкой на равенство не является очевидным, как правило, мы испытываем

if ((oneDouble - anotherDouble) < someTinyValue) 
0

Я думаю, что это линия, которая дает вам проблемы (в .equals методом Fraction:

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

В настоящее время он выполняет целочисленное деление, поэтому 1/2 == 0 и 1/3 == 0, поэтому ваш код рассматривает КАЖДУЮ фракцию уже в списке фракций.

Вы хотите выполнить арифметику с плавающей запятой с каким-то эпсилон.

Why Are Floating Point Numbers Inaccurate?

Смежные вопросы