-1

So here is my problem. I need help trying to figure out what I'm doing wrong and go from there. I need to create a program that runs these instructions.

Create java class named Fraction. This class is used to represent a ratio of two integers. Include mutator methods that allow the user to set the numerator and the denominator. Also include a method to display the fraction on the screen as a ration (e.g. 5/9). This method does not need to reduce the fraction to lowest terms.

The fraction class should contain the following:

• Private instance variables to store the numerator, denominator, and the ratio_value.

• Constructor(s) that set all of the instance variables.

• Public methods to get and set the instance variables.

• A public method named reduce( ) that returns lowest terms of a fraction.

• A public method named toString( ) that returns a String containing the fraction as a ratio.

• A private method name gcd() that return the greatest common divisor of two integers.

Create a test program that allows the user to create array of 7 fractions. Then the program will sort the fraction in ascending order. The highest and the lowest fractions are thrown away and the remaining fractions are added together. The program should display all the fractions and their sum. The sum should be reduced to lowest terms and displayed on the screen. For example, if the sum is 20/60, the program should display 1/3.

Write a sort method in the test program to sort the array of fractions and calculate the sum.

Assume you have the following 7 fractions: 6/7, 2/4, 3/4, 3/18, 1/8, 10/20, 2/6, then an example of the output after throwing away the lowest and the largest fractions, will be:

3 / 18 + 2 / 6 + 2 / 4 + 10 / 20 + 3 / 4 = 9 / 4

I completely lost on how to solve this and stuck where I am at. Below is a copy of my class and .main file. I have some different things that I have tried commented out with '//' so sorry for the long codes in advance. I've tried over and over to figure this and have been stuck for days. It keeps giving me this weird error called null.

How can I get this to work? Thanks.

import java.io.*;
import java.util.*;

public class Arrays_hw5 {

    private static final Scanner keyb = null;
    public static void main(String[] args) {
        Fraction [] fr = new Fraction[7];
        String reduce = "";
        int numerator = 0, denominator = 0;

        Scanner keyb = null;
        FileInputStream fis = null;
        //Scanner keyb = new Scanner(System.in);  
        try {
          fis = new FileInputStream(new File("Fraction"));
              keyb = new Scanner(fis);
       } catch (FileNotFoundException e) {
           e.printStackTrace();}

        for (int i = 0; i < fr.length; i++) {
            //System.out.println("Enter numerator then denominator, hit enter after each entry: ");
           // fr[i] = new Fraction(i, i);
           // fr[i].getNumerator(keyb.nextInt());
           // fr[i].denominator(keyb.nextInt());
           System.out.print(fr[i] + "  ");  }}

    public static void selectionSort(int[]arr)  
    {
        int smallest = 0;
        for (int outer = 0; outer < arr.length - 1; outer++)
        {
            smallest = outer;
            for(int inner = outer + 1; inner < arr.length; inner++)
            {
                if (arr[inner] < arr[smallest])
                    smallest = inner;
            }
            int v = arr[outer];
            arr[outer] = arr[smallest];
            arr[smallest] = v; }
    }
}

Here is the Fraction Class.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Fraction {
    public int numerator = 1;
    public int denominator = 1;
    public int gcd;
    public Fraction() {
        super();
    }
    public Fraction(int n, int d) {
        numerator = n;
        denominator = d;
    }
    public int getNumerator() {
        return numerator;
    }
    public void setNumerator(int numerator) {
        this.numerator = numerator;
    }
    public int getDenominator() {
        return denominator;
    }
    public void setDenominator(int denominator) {
        this.denominator = denominator;
    }
    private static int gcd(int numerator, int denominator) {
        return denominator == 0 ? numerator : gcd(denominator, numerator % denominator);
    }
    public double decimal(double numerator, double denominator) {
        return numerator / denominator;
    }


    public static String reduce(int numerator, int denominator) {
        int gcd = gcd(numerator, denominator);
        return (numerator / gcd) + "/" + (denominator / gcd);
    }
    @Override
    public String toString() {
        return numerator + "/" + denominator;
    }}
Sam Segers
  • 1,951
  • 2
  • 22
  • 28
ohdust
  • 11
  • 1
  • 7
  • 1
    "It keeps giving me this weird error called null." means http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it ? – zapl Nov 29 '15 at 01:35
  • 1
    With `fr[i] = new Fraction(i, i)` uncommented it's printing a lot of `null` because arrays are just containers which are initially empty. You have to put something into them. – zapl Nov 29 '15 at 01:42

1 Answers1

3

Prepare yourself for a long answer. First it is always best to plan out a project before doing any code so here are the steps we will take: 1) Read input from user and store this input into an array of Fractions. 2) Sort this Fraction array then remove (ignore) highest and lowest values in array. 3) Sum all values of array excluding highest and lowest values, reduce this sum, and print this sum to the screen.

Step 1) Read User Input

You are on the right track but you do not read the user input properly. First, you for some reason open a file. This is unnecessary as you only need to read from the command line. Second, you do not read nor store the input properly. I would suggest repeatedly prompting the user to input a numerator then a denominator. And for every time you read one numerator and one denominator, store these values as a Fraction before you re-prompt the user for input. See the following code block to understand what I mean:

Fraction[7] fractions = new Fraction[7]; // array that will hold our fractions
Scanner inputScanner = new Scanner(System.in); // scanner that takes input from the command line

...

public void readInput()
{
    int tempNumer; // variable to store numerator on each iteration
    int tempDenom; // variable to store denominator on each iteration
    for (int i = 0; i < fractions.length; i++)
    {
        System.out.println("Enter a numerator:");
        tempNumer = inputScanner.nexInt();  // store the user-inputted numerator
        System.out.println("Enter a denominator");
        tempDenom = inputScanner.nextInt(); // store the user-inputted denominator
        fractions[i] = new Fraction(tempNumer, tempDenom); // store a Fraction from our temp variables into our fractions array
    }
    
    return;
}

Upon completion of this method, the fractions array will be full of Fraction objects in the order that the user inputted.

Step 2) Sort the fractions array

So, how do we know if a fraction, in normal math, is larger than another fractions? Well, we convert both fractions to have the gcd as each individual fraction's denominator, then we compare the numerators (btw, your gcd method is so wrong. The gcd is between two fraction's denominators, NOT the numerator and denominator of one fraction). The larger numerator at this point is the larger fractions. So, it would be easiest to have a method called fracCompare that takes in two fractions, converts both of them, then return which fraction is larger. We can do this as follows:

public int fracCompare(Fraction fracOne, Fraction fracTwo)
{
    // First, find the gcd of the fractions
    int gcd = gcd(fracOne.getDenominator, fracTwo.getDenominator);
    
    // Now, we need to convert the numerator accordingly
    // We will do this by finding the factor by which the denominator is
    // increased and multiply the numerator by this factor
    int factorOne = gcd / fracOne.getDenominator();
    int tempFracOneNum = fracOne.getNumerator() * factorOne;
    int factorTwo = gcd / fracTwo.getDenominator();
    int tempFracTwoNum = fracTwo.getNumerator() * factorTwo;

    // Now we compare these numerators
    // We will return 1 if fracOne is greater than fracTwo
    // We will return 2 if fracTwo is greater than fracOne
    // We will return 0 if they are the same
    if (tempFracOneNum > tempFracTwoNum)
        return 1;
    else if (tempFracTwoNum > tempFracOneNum)
        return 2;
    else
        return 0;
}

public int gcd(int firstNum, int secondNum)
{
    int a = firstNum.getDenominator();
    int b = secondNum.getDenominator();
    while(a != 0 && b != 0) // until either one of them is 0
    {
        int c = b;
        b = a % b;
        a = c;
    }
    return a+b; // either one is 0, so return the non-zero value
}

A note: I blatantly stole this gcd method from The user, Rushil's answer on another post. Now that we have a compare method, we can sort the array. I will leave the sorting to you because I'm getting sick of formatting code but here is some bubble sort pseudocode to get you started:

i = 0
loop until i = fractions.length - 1
    j = i
    loop until j = fractions.length - 1
    if fraction at j > fraction at j+1
        swap fraction at j and fraction at j+1

Step 3) Sum all Fractions in fractions array

Finally at the last step. In order to add fractions we again need to use the gcd. We use this gdc to see what to increase the numerator of both adding fractions by. We will then take this sum and add it to all the other values in the array. Finally, we will reduce the large sum.

int tempGcd;
int tempFactorOne;
int tempFactorTwo;
Fraction sum = fractions[1];
for (int i = 2; i < fractions.length - 2; i++) // we loop from 2 to fractions.length-2 because 
                                               // we ignore the least and greatest values in the array
                                               // and we assigned the initial sum to the first fraction
{
    tempGcd = gcd(sum.getDenominator(), fractions[i].getDenominator());
    tempFactorOne = tempGcd / sum.getDenominator();
    tempFactorTwo = tempGcd / fractions[i].getDenominator();
    
    sum.setNumerator(tempFactorOne * sum.getNumerator() + tempFactorTwo * fractions[i].getNumerator()); // add the numerators and store as the sum
    sum.setDenominator(gcd); // obviously the denominator is the gcd
}

Hopefully this all should work. I'm sick of typing so I'll leave the reducing of the fraction to you. It is pretty simple--you just need to find the greatest common divisor of the numerator and denominator and then divide both by that divisor. Sorry if my exact code doesn't compile, I'm too lazy to do it myself and you shouldn't be plagiarizing for a school project anyway.

Community
  • 1
  • 1
bpgeck
  • 1,592
  • 1
  • 14
  • 32