I will begin this question with the disclaimer that it is homework but my code is written and working, I just want to know if there any ways in which I can improve what I already have. I want my programs to be as clean and easy to understand as possible.
My task is to Build two classes (Fraction and FractionCounter) and a Driver for use in counting the number of unique fractions read from a text file. Would it be more efficient to use ArrayList? If so, should it be an array to store the unique instances of fractions or should it store fractions that have no double instances? Are there other alternatives to this?
public class FractionDriver {
public static void main(String[] args){
// creates scanner object
Scanner fractions = null;
boolean [] repeated = new boolean [100]; //creates boolean array for repeats
int repeat = 1; //sets repeat counter to 1
// 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("FILE NOT FOUND OR NOT OPENED");
System.exit(0);
}
// creates a large array that stores data from the text file
String[] input = new String[100];
int n= 0; // counts the number of fractions
int numElement = 0; // counts the current index element
//loops through file to store data to input array
while(fractions.hasNext()){
input[numElement] = fractions.next();
numElement++; //increments with each loop
n++; //increments number of fractions
}
if (n == 0) { //if n = 0, nothing was found in the .txt file
System.out.println("No fractions found.");
}
fractions.close(); // closes the input stream
// create object list of fractions
ObjectList fractionList = new ObjectList(n);
ObjectList fracCount = new ObjectList(n);
int totalFractions = 0;
for(int i = 0; i < n; i++){ //loops through fractions
// splits fractions to be stored in respective numerator and denom arrays
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 denominatoris not zero
if(f.getDenominator() != 0){
fractionList.add(f);
for(int j = 0; j <=i; j++){ //loops through fractions
if(fracCount.get(j) != null){
if(!f.equals(fracCount.get(j))){ //checks if two values are equal
fracCount.add(f); //calls add method
}else{
count.compareAndIncrement(f); //calls compareAndIncrement() method
repeat++;//increments repeat value
}
}
}
if (repeated[i] == false) { //checks if I has been printed
if(repeat == count.counted()) {
System.out.println(count.toString(f)); //calls toString() to print counts
repeated[i] = true;//says i has been printed
}
}
}
}
}
}
Here are the linked constructor classes.
Fraction counter:
public class FractionCounter extends Fraction{
private Fraction theFraction;
private int counter = 1; // sets starting value for counting variable
FractionCounter(Fraction theFraction) {
this.theFraction = theFraction;
}
/*
* compares and increments values
*/
boolean compareAndIncrement (Fraction newFraction) {
if((theFraction.getNumerator() / theFraction.getDenominator() ==
newFraction.getNumerator() / newFraction.getDenominator())){
counter++; //increments
return true;
}else if(theFraction.getDenominator() == 0 || newFraction.getDenominator() == 0){
return false;
} else {
return false;
}
}
/*
* checks if have been countes
*/
public int counted () {
return counter;
}
/*
* returns as a string
*/
public String toString(Fraction f) {
return theFraction + " has a count of " + counter;
}
}
Fraction Class:
public class Fraction {
private int numerator; //only data elements
private int denominator;
/*
* empty constructor
*/
Fraction() {
}
/*
* Sets numerator and denominator values
*/
Fraction(int x, int y) {
reduce(x,y);
}
/*
* re duces numerator and denominator and checks if denominator euals zero,
* in which case an error will be printed.
*/
private void reduce(int numerator, int denominator) {
int max = numerator; //sets max for GCD check
int gcd = 1;
//checks if both negative so it can be changed to positive
if (numerator < 0 && denominator < 0) {
this.numerator = Math.abs(numerator);
this.denominator = Math.abs(denominator);
}
//checks for a divide by zero
if (denominator == 0) {
System.err.println("Invalid fraction - cannot devide by zero"); //dividebyzeroexception????
System.exit(0);
}
//finds GCD
if (denominator > numerator) {
max = denominator;
}
for (int i = 1; i <= max; i++) {
if (numerator % i == 0 && denominator % i == 0) {
gcd = i;
}
}
//sets new values based on GCD
if (gcd != 1) {
this.numerator = numerator / gcd;
this.denominator = denominator / gcd;
} else {
this.numerator = numerator;
this.denominator = denominator;
}
}
/*
* checks for equality between passed Fraction object and current one
*/
public boolean equals(Fraction other) {
if (other == null) {
return false;
}
if (!(other instanceof Fraction)) {
return false;
}
Fraction that = other;
return this.numerator == that.numerator && this.denominator == that.denominator;
}
/*
* returns numerator
*/
public int getNumerator() {
return numerator;
}
/*
* sets numerator to given value
*/
public void setNumerator(int x) {
numerator = x;
}
/*
* returns denominator
*/
public int getDenominator() {
return denominator;
}
/*
* sets denominator to given value
*/
public void setDenominator(int y) {
denominator = y;
}
/*
* returns fraction as string
*/
public String toString() {
return numerator + "/" + denominator;
}
}