/**
* Students: Jennifer Yu (mainly FractionMain class) & Samar Qureshi (mainly Fraction class)
* Course: ICS4U
* Date: November 9, 2021
* The Fraction Main class allows the user to find the harmonic sum of a natural number and the approximation of the Maclaurin series for e^x for an x value (integer). Additionally, it provides the user with other options such as converting to and from improper fractions, simplifying fractions, calculating expressions containing fractions, converting decimals to fractions, and sorting a list of fractions from least to greatest. These actions are done with the help of Fraction objects.
*/
import java.util.Scanner;
public class FractionMain {
private static final Scanner INPUT = new Scanner(System.in);
public static void main(String[] args) {
// declarations
String userInput;
int userChoice;
Fraction harmonicSum = new Fraction(), eX = new Fraction(), frac;
long[] fraction, mixed;
do {
// main menu
System.out.println("\\nMAIN MENU");
System.out.println("0 - Exit");
System.out.println("1 - Find the harmonic sum of a number x"); // x is for the superscript for option 2
System.out.println("2 - Approximate e to the power of a number using the Maclaurin Series for e");
System.out.println("3 - Convert improper fraction to mixed number");
System.out.println("4 - Convert mixed number to improper fraction");
System.out.println("5 - See the simplified form of a fraction");
System.out.println("6 - Fraction calculator");
System.out.println("7 - Convert decimal to fraction");
System.out.println("8 - Sort a list of fractions from least to greatest");
System.out.print("Enter your choice: ");
userInput = INPUT.nextLine();
userChoice = makeInt(userInput);
System.out.println();
// corresponding choices
if (userChoice == 1) {
System.out.println("\\nHARMONIC SUM");
harmonicSum = inputHarmonicSum();
} else if (userChoice == 2) {
System.out.println(" x"); // to imitate superscript for e^x in the console
System.out.println("MACLAURIN SERIES FOR e");
eX = inputMaclaurinSeries();
} else if (userChoice == 3) {
System.out.println("\\nIMPROPER FRACTION --> MIXED NUMBER");
fraction = inputConvertToMixed(harmonicSum, eX); // get input
frac = new Fraction(fraction[0], fraction[1]); // construct frac
displayConvertToMixed(frac); // convert to mixed number & display
} else if (userChoice == 4) {
System.out.println("\\nMIXED NUMBER --> IMPROPER FRACTION");
mixed = inputConvertToImproper();
frac = new Fraction(mixed[0], mixed[1], mixed[2]); // construct frac; whole number, numerator, denominator
displayConvertToImproper(frac); // convert to improper & display
} else if (userChoice == 5) {
System.out.println("\\nFRACTION IN SIMPLEST FORM");
fraction = inputSimplifyFraction();
// construct frac & simplify it
frac = new Fraction(fraction[0], fraction[1]);
displaySimplifyFraction(frac);
} else if (userChoice == 6) {
System.out.println("\\nFRACTION CALCULATOR");
inputCalculate();
} else if (userChoice == 7) {
System.out.println("\\nDECIMAL TO FRACTION");
inputConvertToFraction();
} else if (userChoice == 8) {
System.out.println("\\nSORT ARRAY OF FRACTIONS");
outputFracArr(sortFractions(inputFracArr()));
} else if (userChoice != 0) { // input was either not an integer or not an option
System.out.println("Invalid input. Please try again.");
}
System.out.println();
} while (userChoice != 0);
// farewell message
System.out.println("Goodbye!");
}
/*
* Takes input (limits the input to prevent long overflow when calculating the harmonic sum) and calls the method that calculates and displays the harmonic sum
* Pre: user must have chosen option 1 in the main menu
* Post: returns a Fraction object
*/
public static Fraction inputHarmonicSum() {
// declarations
String userInput;
int userNum;
boolean isValid = false;
Fraction harmonicSum = new Fraction();
// get input and call the calcHarmonicSum method if it is valid; keep repeating while input is invalid
do {
System.out.print("Enter a natural number (from 1 to 43) to find its harmonic sum: ");
userInput = INPUT.nextLine();
userNum = makeInt(userInput); // convert user's input to an int if possible (-1 if the input was not a whole number)
if (userNum != -1 && userNum != 0 && userNum < 44) { // if the input is a natural number, then display the harmonic sum by calling the method (limits the user to natural numbers under 44 to prevent long overflow)
harmonicSum = calcHarmonicSum(userNum);
isValid = true;
} else if (userNum == -1 && userInput.length() > 0 && userInput.charAt(0) == '-' && makeInt(userInput.substring(1)) != -1) { // if the user entered a number but it was not positive, then user its absolute value instead
userNum = makeInt(userInput.substring(1));
if (userNum > 0 && userNum < 44) { // make sure the user's number is between 0 and 44
System.out.println("Although you inputted a negative number, here is the harmonic sum of its absolute value.");
harmonicSum = calcHarmonicSum((int) Math.abs(userNum)); // display the harmonic sum of the absolute value of the user's number
isValid = true;
}
}
// tell user to try again
if (!isValid) {
System.out.println("Remember, it must be a natural number (positive integer) from 1 to 43. Try again.");
}
} while (!isValid);
return(harmonicSum);
}
/*
* Calculates and shows the steps to getting the harmonic sum and displays it to the user. Also returns the harmonic sum as a Fraction object
* Pre: int representing the user's input
* Post: displays the terms of the series and the final harmonic sum, returns the harmonic sum as a Fraction object
*/
public static Fraction calcHarmonicSum(int n) {
// declarations and initializations
Fraction harmonicSum = new Fraction();
Fraction currentFrac;
String[][] fractionArr = new String[n + 1][3];
// adding the fractions
for (int i = 1; i <= n; i++) {
currentFrac = new Fraction(1, i); // construct currentFrac
harmonicSum.add(currentFrac); // add the current fraction to the sum
fractionArr[i - 1] = currentFrac.formatImproper(); // format it for output later
}
// format the harmonic sum
fractionArr[n] = harmonicSum.formatImproper();
// output; go through every numerator first, then fraction bars, then denominators
for (int j = 0; j < fractionArr[0].length; j++) {
for (int i = 0; i < fractionArr.length; i++) {
if (i == fractionArr.length - 1) { // if we are trying to print a part of the harmonic sum, then nothing comes after
System.out.println(fractionArr[i][j]);
} else if (i == fractionArr.length - 2 && j == 1) { // if we are printing the fraction bar of the last term, it must be followed by =
System.out.print(fractionArr[i][j] + " = ");
} else if (j != 1) {
System.out.print(fractionArr[i][j] + " "); // if we are printing the numerator or denominator of a term
} else {
System.out.print(fractionArr[i][j] + " + "); // if we are printing the fraction bar of a term, then we must also add a + to show that we are adding
}
}
}
// decimal output
System.out.println("\\nAs a decimal, the harmonic sum of " + n + " is " + harmonicSum.calcDecimal());
return(harmonicSum);
}
/*
* Takes input and calls the method that calculates the approximation of e^x for the inputted x value
* Pre: user must have chosen option 2 in the main menu
* Post: returns a Fraction object
*/
public static Fraction inputMaclaurinSeries() {
// declarations
String userInput;
int userNum;
boolean isValid = false;
Fraction eX = new Fraction();
do {
// get user input & convert to integer
System.out.print("Enter an integer, x, from -4 to 6 to find the approximation of e to the power of x: ");
userInput = INPUT.nextLine();
userNum = makeInt(userInput);
// call the method that calculates e^x if the input is valid
if (userNum != -1 && userNum < 7) { // whole number, less than 7 to ensure that the answer is somewhat accurate
eX = calcMaclaurinSeries(userNum);
isValid = true;
} else if (userNum == -1 && userInput.length() > 0 && userInput.charAt(0) == '-' && makeInt(userInput.substring(1)) != -1) { // negative integer
userNum = -makeInt(userInput.substring(1));
if (userNum > -5) { // limits the input to prevent long overflow
eX = calcMaclaurinSeries(userNum);
isValid = true;
}
userNum = 1; // or else the do while loop will continue to run
}
// invalid input message
if (!isValid) {
System.out.println("Remember, it must be an integer (from -4 to 6). Try again.");
}
} while (!isValid);
return(eX);
}
/*
* Calculates the approximation for e^x given an x value, displays it to the user, and returns the fraction object.
* Pre: int for x
* Post: displays the approximation for e^x, returns a Fraction object
*/
public static Fraction calcMaclaurinSeries(int x) {
// declarations & initializations
String[] fractionArr = new String[3];
Fraction sum = new Fraction();
Fraction currentFrac;
// calculating
for (int i = 0; i < 15; i++) { // the more iterations of the loop, the lower the number the user can input for x because a long is only 64 bits (-2^61 to 2^61-1) so after that, the fraction won't be accurate. But, this also means the approximation will not be as close given larger x values
currentFrac = new Fraction((long) Math.pow(x, i), calcFactorial(i)); // maclaurin series for e^x
currentFrac.simplify(); // reduce the fraction to lowest terms to try and prevent long overflow
sum.add(currentFrac);
sum.simplify(); // reduce the fraction to lowest terms to try and prevent long overflow
// prevent long overflow when x = 1 or -1
if (Math.abs(x) == 1 && i == 13) {
i = 15;
}
}
fractionArr = sum.formatImproper();
// output
System.out.println(" " + x + getSpaces(" is approximately equal to: ".length()) + fractionArr[0]); // x is to act as the superscript of e^x
System.out.println("e" + getSpaces((x + "").length()) + " is approximately equal to: " + fractionArr[1]);
System.out.println(getSpaces(1 + (x + "").length() + " is approximately equal to: ".length()) + fractionArr[2]);
// decimal output
System.out.println("\\nAs a decimal, it is approximately " + sum.calcDecimal());
return(sum);
}
/*
* Takes input of what the user would like to convert (either the harmonic sum, ex, or a new fraction) and ensures that if the user wants to convert a new fraction, it is valid
* Pre: two Fraction objects (harmonic sum and e^x), user must have chosen option 3 from the main menu
* Post: returns a long array
*/
public static long[] inputConvertToMixed(Fraction harmonicSum, Fraction eX) {
// declarations
String userInput;
char userSubChoice;
long[] fraction = new long[2];
// display options and make user choose
do {
// options
System.out.println("A - Convert the harmonic sum to mixed number x");
System.out.println("B - Convert the Maclaurin Series approximation of e to mixed number");
System.out.println("C - Convert a new fraction to a mixed number");
System.out.print("Enter your choice: ");
userInput = INPUT.nextLine();
// convert to correct char
if (userInput.length() != 1) {
userSubChoice = 'z';
} else {
userSubChoice = userInput.toUpperCase().charAt(0);
}
// invalid message
if (userSubChoice < 65 || userSubChoice > 67) {
System.out.println("That is invalid. Try again.\\n");
}
} while (userSubChoice < 65 || userSubChoice > 67); // keeps looping while it isn't A, B, or C
// run corresponding option
if (userSubChoice == 'A') { // harmonic sum
fraction[0] = harmonicSum.getNumerator();
fraction[1] = harmonicSum.getDenominator();
} else if (userSubChoice == 'B') { // e^x
fraction[0] = eX.getNumerator();
fraction[1] = eX.getDenominator();
} else { // user fraction
do {
System.out.print("Enter a fraction to display as a mixed number: ");
fraction = checkValidFraction(INPUT.nextLine());
} while (fraction[1] == 0); // while invalid fraction (aka denominator = 0)
}
return(fraction);
}
/*
* Displays the equivalent mixed number given an improper fraction
* Pre: Fraction object
* Post: returns nothing but displays the mixed number to the user
*/
public static void displayConvertToMixed(Fraction frac) {
// declaration & initialization
String[][] fractionArr = new String[2][3]; // fractionArr[0] will be the improper fraction and fractionArr[1] will have part of the fraction part of the mixed number
fractionArr[0] = frac.formatImproper(); // format improper fraction
// get the mixed number values of the fraction
frac.improperToMixed();
fractionArr[1] = frac.formatMixed(); // format mixed number
System.out.println();
// output
if (frac.getWholeNumber() == 0) { // normal fraction
System.out.println(fractionArr[0][0] + getSpaces(" as a mixed number is equal to: ".length())+ fractionArr[1][0]); // numerators
System.out.println(fractionArr[0][1] + " as a mixed number is equal to: " + fractionArr[1][1]); // fraction bars & words
System.out.println(fractionArr[0][2] + getSpaces(" as a mixed number is equal to: ".length()) + fractionArr[1][2]); // denominators
} else if (frac.getDenominator() == 1) { // whole number
System.out.println(fractionArr[0][0]); // numerators
System.out.println(fractionArr[0][1] + " as a mixed number is equal to: " + frac.getWholeNumber()); // words and whole number of mixed number
System.out.println(fractionArr[0][2]); // denominators
} else {
System.out.println(fractionArr[0][0] + getSpaces(" as a mixed number is equal to: ".length() + (frac.getWholeNumber() + "").length() + 1) + fractionArr[1][0]); // numerators
System.out.println(fractionArr[0][1] + " as a mixed number is equal to: " + frac.getWholeNumber() + " " + fractionArr[1][1]); // fraction bars & words, and whole number of mixed number
System.out.println(fractionArr[0][2] + getSpaces(" as a mixed number is equal to: ".length() + (frac.getWholeNumber() + "").length() + 1) + fractionArr[1][2]); // denominators
}
}
/*
* Takes input of a mixed number
* Pre: user must have chosen option 4 from the main menu
* Post: returns a long array
*/
public static long[] inputConvertToImproper() {
// declaration
long[] mixed = new long[3];
// get input
do {
System.out.print("Enter a mixed number to display as an improper fraction (e.g. 2 5/13): ");
mixed = checkValidMixed(INPUT.nextLine().trim()); // remove spaces from start & end to help with checking for valid mixed
} while (mixed[2] == 0); // denominator = 0 --> invalid input
return(mixed);
}
/*
* Displays the equivalent improper fraction given a mixed number
* Pre: Fraction object
* Post: returns nothing but displays the improper fraction to the user
*/
public static void displayConvertToImproper(Fraction frac) {
// declaration
String[][] fractionArr = new String[2][3];
boolean alreadyImproper = true;
// initializing/assigning values
fractionArr[0] = frac.formatMixed();
// formatting the user's mixed number
if (frac.getWholeNumber() != 0) {
alreadyImproper = false; // the fraction given is mixed
fractionArr[0][0] = getSpaces((frac.getWholeNumber() + "").length() + 1) + fractionArr[0][0];
fractionArr[0][1] = frac.getWholeNumber() + " " + fractionArr[0][1];
fractionArr[0][2] = getSpaces((frac.getWholeNumber() + "").length() + 1) + fractionArr[0][2];
} else if (frac.getDenominator() == 1) { // no need to show denominator
fractionArr[0][0] = getSpaces((frac.getMixedNumerator() + "").length());
fractionArr[0][1] = frac.getMixedNumerator() + "";
fractionArr[0][2] = getSpaces((frac.getMixedNumerator() + "").length());
}
frac.mixedToImproper();
fractionArr[1] = frac.formatImproper();
System.out.println();
// output
if (alreadyImproper) { // the whole number was always 0 (even before converting)
System.out.println(fractionArr[1][0]);
System.out.println(fractionArr[1][1] + " is already an improper fraction!");
System.out.println(fractionArr[1][2]);
} else { // regular case
System.out.println(fractionArr[0][0] + getSpaces(" as an improper fraction is equal to: ".length()) + fractionArr[1][0]);
System.out.println(fractionArr[0][1] + " as an improper fraction is equal to: " + fractionArr[1][1]);
System.out.println(fractionArr[0][2] + getSpaces(" as an improper fraction is equal to: ".length()) + fractionArr[1][2]);
}
}
/*
* Takes input of what the user would like to simplify
* Pre: user must have chosen option 5 in the main menu
* Post: returns a long array
*/
public static long[] inputSimplifyFraction() {
// declaration
long[] fraction = new long[2];
// get input
do {
System.out.print("Enter a fraction to simplify: ");
fraction = checkValidFraction(INPUT.nextLine());
} while (fraction[1] == 0); // keep looping until a valid fraction is entered
return(fraction);
}
/*
* Displays the simplified fraction
* Pre: Fraction object
* Post: doesn't return anything but displays the formatted, simplified fraction
*/
public static void displaySimplifyFraction(Fraction frac) {
// declaration & initialization
String[] fractionArr = new String[3];
frac.simplify(); // simplify fraction if possible
fractionArr = frac.formatImproper();
// output
if (frac.getDenominator() == 1) {
System.out.println(fractionArr[0]); // only display the numerator if the denominator is 1
} else {
for (int i = 0; i < fractionArr.length; i++) { // display full fraction
System.out.println(fractionArr[i]);
}
}
}
/*
* Insists for a string containing a valid expression with fractions as input and calls the method that calculates the expression
* Pre: user must have chosen option 6 from the main menu
* Post: returns nothing
*/
public static void inputCalculate() {
// declarations
String userInput;
// get valid input
do {
System.out.println("Enter an expression containing fractions (e.g. 3/5 + 7/2 * 18/29). You can use the following symbols: ");
System.out.println(" o Addition --> +\\n o Subtraction --> _\\n o Multiplication --> *\\n o Division --> |");
System.out.print("Enter an expression (use +, _, *, |): "); // subtraction & division operators are different to avoid confusion with negatives and fraction bars
userInput = checkValidExpression(INPUT.nextLine());
// invalid input message
if (userInput.equals("invalid")) {
System.out.println("Invalid expression. Try again.\\n");
}
} while (userInput.equals("invalid")); // keep asking for a valid expression
calculate(userInput);
}
/*
* Calculates the expression following the order of operations (multiplication & division before addition & subtraction) and displays the final fraction and decimal
* Pre: String
* Post: returns nothing but displays the final fraction and decimal
*/
public static void calculate(String expression) {
// declarations
boolean hasDM = false; // BEDMAS --> DM = division/multiplication
Fraction frac;
long[] fractionArr;
// calculate the expression; multiplication/division come before addition/subtraction
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) == '*') {
expression = evaluate(expression, i, '*');
i = -1; // restart from the beginning of the expression
} else if (expression.charAt(i) == '|') {
expression = evaluate(expression, i, '|');
i = -1;
} else if (i == expression.length() - 1 && !hasDM) {
hasDM = true; // lets the program know that addition/subtraction can occur now
i = -1;
} else if (hasDM && expression.charAt(i) == '+') {
expression = evaluate(expression, i, '+');
i = -1;
} else if (hasDM && expression.charAt(i) == '_') {
expression = evaluate(expression, i, '_');
i = -1;
}
}
// format and output
fractionArr = checkValidFraction(expression);
frac = new Fraction(fractionArr[0], fractionArr[1]);
displaySimplifyFraction(frac);
System.out.println("As a decimal, it is " + frac.calcDecimal());
}
/*
* Takes input of a valid decimal and calls a method to convert it to a fraction and display it
* Pre: user must have chosen option 7 from the main menu
* Post: returns nothing
*/
public static void inputConvertToFraction() {
// declarations
Fraction frac = new Fraction();
String userInput;
boolean isValid;
// get valid input
do {
isValid = true;
System.out.print("Enter a decimal: ");
userInput = INPUT.nextLine();
if (userInput.replaceAll("\\\\.", "").length() + 1 < userInput.length()) { // more than one decimal
isValid = false;
} else if (makeInt(userInput.replaceAll("\\\\.", "")) == -1 && userInput.length() > 0 && makeInt(userInput.replaceAll("\\\\.", "").substring(1)) == -1) { // not negative or positive
isValid = false;
} else if (userInput.length() == 0) { // empty string
isValid = false;
}
} while (!isValid);
// convert & display
frac.decimalToFrac(userInput);
displaySimplifyFraction(frac);
}
/*
* Evaluates part of the according to the operator given
* Pre: String expression, int (index), char operator
* Post: returns a string
*/
public static String evaluate(String expression, int i, char operator) {
// declarations
Fraction frac1, frac2;
int previousOperator, nextOperator;
long[] fraction;
// find the start and end of the binomial
previousOperator = findPreviousOperator(expression, i);
nextOperator = findNextOperator(expression, i);
// make sure the terms before and after the operator are valid
fraction = checkValidFraction(expression.substring(previousOperator + 1, i)); // get numerator & denominator
frac1 = new Fraction(fraction[0], fraction[1]); // create fraction
fraction = checkValidFraction(expression.substring(i + 1, nextOperator));
frac2 = new Fraction(fraction[0], fraction[1]); // create fraction
// evaluate accordingly
if (operator == '*') {
frac1.multiply(frac2);
} else if (operator == '|') {
frac1.divide(frac2);
} else if (operator == '+') {
frac1.add(frac2);
} else {
frac1.subtract(frac2);
}
// replace the two terms with the answer and return
return(expression.substring(0, previousOperator + 1) + frac1 + expression.substring(nextOperator));
}
/*
* Finds the nearest operator (+, _, *, |) BEFORE the index given
* Pre: String, int
* Post: returns an int
*/
public static int findPreviousOperator(String expression, int index) {
// find & return the index of the operator that comes before the index given
for (int i = index - 1; i > 0; i--) {
if (expression.charAt(i) == '+' || expression.charAt(i) == '_' || expression.charAt(i) == '*' || expression.charAt(i) == '|') {
return(i);
}
}
return(-1);
}
/*
* Finds the nearest operator AFTER the index given
* Pre: String, int
* Post: returns an int
*/
public static int findNextOperator(String expression, int index) {
// find and return the index of the operator that comes after the index given
for (int i = index + 1; i < expression.length(); i++) {
if (expression.charAt(i) == '+' || expression.charAt(i) == '_' || expression.charAt(i) == '*' || expression.charAt(i) == '|') {
return(i);
}
}
return(expression.length());
}
/*
* Returns a string containing a valid expression or "invalid" if the expression is invalid
* Pre: String
* Post: returns a formatted String
*/
public static String checkValidExpression(String potential) {
// declarations & initializations
int nextOperator = -1;
potential = potential.replaceAll(" ", ""); // remove spaces
// checking validity
for (int i = 0; i < potential.length(); i++) {
// look for the next operator
nextOperator = findNextOperator(potential, i);
// see if the term is valid
if (checkValidFraction(potential.substring(i, nextOperator))[1] == 0) { // denominator = 0, meaning invalid fraction
return("invalid");
}
i = nextOperator; // check next term in the next iteration
}
// return invalid if the last character of the potential expression is an operator
if (makeInt(potential.charAt(potential.length() - 1) + "") == -1) {
return("invalid");
}
// return formatted (spaces removed) valid expression
return(potential);
}
/*
* Checks if the given String contains a valid fraction (numerator/denominator). If so, then it returns a long array containing two elements: the numerator and the denominator. If not, then long array returned has the denominator equal to 0
* Pre: String
* Post: returns a long array
*/
public static long[] checkValidFraction(String potentialFrac) {
// declarations & initialization
String potentialN, potentialD;
int slashIndex = -1;
long[] frac = new long[2];
potentialFrac = potentialFrac.replaceAll(" ", ""); // remove all spaces
// see how many /s and where
for (int i = 0; i < potentialFrac.length(); i++) {
if (potentialFrac.charAt(i) == '/' && slashIndex == -1 && i + 1 != potentialFrac.length()) {
slashIndex = i;
frac[1] = 1;
} else if (potentialFrac.charAt(i) == '/') { // string has more than 1 slash or the slash is at the end, making it an invalid fraction for our purposes
frac[1] = 0;
return(frac);
}
}
// if there was no slash (potential integer)
if (slashIndex == -1) {
frac[1] = 1;
if (makeInt(potentialFrac) != -1) {
frac[0] = makeInt(potentialFrac);
} else if (potentialFrac.length() > 0 && potentialFrac.charAt(0) == '-' && makeInt(potentialFrac.substring(1)) != -1) {
frac[0] = -makeInt(potentialFrac.substring(1));
} else {
frac[1] = 0;
}
return(frac);
}
// initialize the potential numerator & denominator
potentialN = potentialFrac.substring(0, slashIndex);
potentialD = potentialFrac.substring(slashIndex + 1);
// assigning the correct numerator to the long array
if (makeInt(potentialN) != -1) {
frac[0] = makeInt(potentialN);
} else if (potentialN.length() > 0 && potentialN.charAt(0) == '-' && makeInt(potentialN.substring(1)) != -1) {
frac[0] = -makeInt(potentialN.substring(1));
} else {
frac[1] = 0;
return(frac); // means that the fraction is invalid since the denominator is 0
}
// assigning the correct denominator to the long array
if (makeInt(potentialD) != -1 && makeInt(potentialD) != 0) { // make sure that not only is denominator an integer but it also isn't 0
frac[1] = makeInt(potentialD);
} else if (potentialD.length() > 0 && potentialD.charAt(0) == '-' && makeInt(potentialD.substring(1)) != -1 && makeInt(potentialD.substring(1)) != 0) {
frac[1] = -makeInt(potentialD.substring(1));
} else {
frac[1] = 0;
return(frac); // means that the fraction is invalid
}
return(frac);
}
/*
* Checks if the given String contains a valid mixed number (wholeNum numerator/denominator where numerator and denominator are positive). If so, then a long array containing three elements (wholeNum, numerator, denominator) is returned. Otherwise, the long array is returned with the denominator equal to 0.
* Pre: String
* Post: returns a long array
*/
public static long[] checkValidMixed(String potentialMixed) {
// declarations & initializations
long[] mixed = new long[3], frac = new long[2];
int spaceStart, spaceEnd = -1, slashIndex;
String potentialWhole, potentialFrac;
// Check that there is a space section (separates whole vs. fraction) & it comes before /, if there are any
spaceStart = potentialMixed.indexOf(" ");
slashIndex = potentialMixed.indexOf("/");
if (slashIndex != -1 && slashIndex < spaceStart) {
return(mixed); // denominator will be 0 to signal invalid mixed
} else if (spaceStart == -1) {
potentialFrac = potentialMixed; // no space
} else {
// find spaceEnd
for (int i = spaceStart; i < potentialMixed.length(); i++) {
if (potentialMixed.charAt(i) != ' ') {
spaceEnd = i - 1;
i = potentialMixed.length(); // exit the loop once space section ends
}
}
// initialize strings
potentialWhole = potentialMixed.substring(0, spaceStart);
potentialFrac = potentialMixed.substring(spaceEnd + 1);
// convert to int
// whole part
if (makeInt(potentialWhole) != -1) {
mixed[0] = makeInt(potentialWhole);
} else if (potentialWhole.length() > 0 && potentialWhole.charAt(0) == '-' && makeInt(potentialWhole.substring(1)) != -1) {
mixed[0] = -makeInt(potentialWhole.substring(1));
} else {
return(mixed); // not an int
}
}
// fraction part
// if the fraction part is negative instead of the whole number, make the user try again
if (potentialFrac.indexOf("-") != -1 && slashIndex != -1) {
return(mixed); // signals invalid input since denominator = 0
}
frac = checkValidFraction(potentialFrac);
mixed[1] = frac[0];
mixed[2] = frac[1]; // will indicate whether or not the fraction & mixed number were valid
return(mixed);
}
/*
* Calculates the factorial of a given integer
* Pre: int
* Post: returns a long
*/
public static long calcFactorial(int num) {
long factorial = 1;
// calculate
for (int i = num; i > 1; i--) {
factorial *= i;
}
return(factorial);
}
/*
* Returns a string with the specified number of spaces
* Pre: int representing the number of spaces
* Post: returns a string containing spaces
*/
public static String getSpaces(int numSpaces) {
// declare & initialize an empty string to be returned at the end
String returnStr = "";
// add spaces to the return string
for (int i = 0; i < numSpaces; i++) {
returnStr += " ";
}
return(returnStr);
}
/*
* Converts the given string into an integer
* Pre: String (number must be positive)
* Post: returns the integer, and -1 if the string is not a number
*/
public static int makeInt(String str) {
// declaration and initialization
int returnInt = -1;
int multiplier = (int) Math.pow(10, str.length() - 1);
boolean isAllInt = true;
// check for int digits
for (int i = 0; i < str.length() && isAllInt; i++) {
if (str.charAt(i) < 48 || str.charAt(i) > 57) { // if the char is not in this ascii range, it is not a digit
isAllInt = false;
}
}
// calculate the int value
if (isAllInt && str.length() > 0) {
returnInt = 0;
for (int i = 0; i < str.length(); i++, multiplier /= 10) {
returnInt += (str.charAt(i) - 48) * multiplier;
}
}
return(returnInt);
}
/*
* SAMAR CODE: Takes input of the valid fractions to be sorted from least to greatest
* Pre: user must have chosen option 8 from the main menu
* Post: returns a Fraction array
*/
public static Fraction[] inputFracArr(){
long[]fraction;
String arrSize;
do {
System.out.print("How many fractions would you like to sort?: ");
arrSize = INPUT.nextLine();
} while (makeInt(arrSize) < 1);
Fraction [] arr = new Fraction [(int)Fraction.parseLong(arrSize)]; //creates a Fraction array of arrSize number of Fractions
for(int i = 0; i<arr.length; i++){
do {
System.out.print("Enter fraction " + (i+1) + ": ");
fraction = checkValidFraction(INPUT.nextLine());
} while (fraction[1] == 0); // while invalid fraction (aka denominator = 0)
arr[i] = new Fraction(fraction[0], fraction[1]);
}
return arr;
}
/*
* SAMAR CODE: Sorts the Fractions in the array from least to greatest using bubble sort
* Pre: Fraction array
* Post: returns the fraction array
*/
public static Fraction[] sortFractions(Fraction[]arr){ //sorts a fraction array from least to greatest
Fraction temp;;
for (int i = 0; i<arr.length-1; i++) {
for (int j = 0; j<arr.length-1-i; j++) {
if(arr[j].calcDecimal() > arr[j+1].calcDecimal()) {
temp = new Fraction(arr[j].getNumerator(), arr[j].getDenominator());
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
/*
* SAMAR CODE: Displays the elements in the sorted fraction array, each separated by a comma
* Pre: Fraction array
* Post: returns nothing but displays the elements to the user
*/
public static void outputFracArr(Fraction[]arr){
System.out.print("Your sorted fractions: ");
for(int i = 0; i<arr.length; i++){
System.out.print(arr[i].toString());
if(i<arr.length-1){
System.out.print(", ");
}
}
System.out.println();
}
}
FractionMain v2 (without static final Scanner)