Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*************************************************
- * A class for representing rational numbers.
- * @author Edvin Lam
- * @author Lucas Ravens
- * @assignment 43, Lab 2
- * @version 0.2
- ************************************************/
- public class RatNum {
- private int numerator;
- private int denominator = 1;
- /**
- * Creates a new default RatNum object with a numerator of 0 and a denominator of 1.
- */
- public RatNum(){
- numerator = 0;
- denominator = 1;
- }
- /**
- * Creates a new RatNum object with a specified numerator and a denominator of 1.
- * @param a The numerator of the rational number.
- */
- public RatNum(int a){
- numerator = a;
- }
- /**
- * Creates a new RatNum object with a specified numerator and denominator.
- * @param a The numerator of the rational number.
- * @param b The denominator of the rational number.
- */
- public RatNum(int a, int b){
- if (b == 0) throw new NumberFormatException("Denominator = 0");
- numerator = a/gcd(a,b);
- denominator = b/gcd(a,b);
- if (numerator < 0 && denominator < 0) {
- numerator = Math.abs(numerator);
- denominator = Math.abs(denominator);
- } else if (denominator < 0) {
- denominator = (-1)*denominator;
- numerator = (-1)*numerator;
- }
- }
- /**
- * Creates a copy of an existing RatNum object.
- * @param r The RatNum object to copy.
- */
- public RatNum(RatNum r){
- numerator = r.getNumerator();
- denominator = r.getDenominator();
- }
- /**
- * Creates a new RatNum object from a string.
- * @param s The rational number in the form of "a/b", where a and b are integers.
- */
- public RatNum(String s){
- this((RatNum)parse(s));
- }
- /**
- * Returns the numerator as an integer.
- * @return Numberator as an integer.
- */
- public int getNumerator(){
- return numerator;
- }
- /**
- * Returns the denominator as an integer.
- * @return Denominator as integer.
- */
- public int getDenominator(){
- return denominator;
- }
- /**
- * Creates a string representation of this RatNum.
- * Overrides toString.
- * @return a string representation of this RatNum.
- */
- public String toString() {
- return numerator+"/"+denominator;
- }
- /**
- * Creates a double representation of this RatNum.
- * Not to be used in any calculations, as it probably would result in rounding errors.
- * Instead to be used to represent the final RatNum, after calculations.
- * @return a double representation of this RatNum
- */
- public double toDouble() {
- return (double)numerator/denominator;
- }
- /**
- * Creates a copy of this RatNum as a new object.
- * @return a new RatNum object.
- * @throws CloneNotSupportedException if object isn't a RatNum object.
- */
- public Object clone()throws CloneNotSupportedException {
- return super.clone();
- }
- /**
- * Method for addition of two RatNum objects.
- * @param r, the RatNum object to perform the addition with.
- * @return a new RatNum object.
- */
- public RatNum add(RatNum r) {
- int numerator2 = r.getNumerator();
- int denominator2 = r.getDenominator();
- int newDenominator = denominator*denominator2;
- int newNumerator = numerator*denominator2+numerator2*denominator;
- return new RatNum(newNumerator, newDenominator);
- }
- /**
- * Method for subtraction of two RatNum objects.
- * @param r, the RatNum object to perform the subtraction with.
- * @return a new RatNum object.
- */
- public RatNum sub(RatNum r) {
- int numerator2 = r.getNumerator();
- int denominator2 = r.getDenominator();
- int newDenominator = denominator*denominator2;
- int newNumerator = numerator*denominator2-numerator2*denominator;
- return new RatNum(newNumerator, newDenominator);
- }
- /**
- * Method for multiplying two RatNum objects.
- * @param r, the RatNum object to perform the multiplication with.
- * @return a new RatNum object.
- */
- public RatNum mul(RatNum r) {
- int numerator2 = r.getNumerator();
- int denominator2 = r.getDenominator();
- int newDenominator = denominator*denominator2;
- int newNumerator = numerator*numerator2;
- return new RatNum(newNumerator, newDenominator);
- }
- /**
- * Method for dividing two RatNum objects.
- * @param r, the RatNum object to perform the division with.
- * @return a new RatNum object.
- */
- public RatNum div(RatNum r) {
- int numerator2 = r.getNumerator();
- int denominator2 = r.getDenominator();
- int newDenominator = denominator*numerator2;
- int newNumerator = numerator*denominator2;
- return new RatNum(newNumerator, newDenominator);
- }
- /**
- * Method for comparing two RatNum objects, to determine whether they are equal.
- * @param r, the RatNum object to compare with.
- * @return a boolean, true if equal.
- */
- public boolean equals(Object r) {
- if (r == null || this.getClass() != r.getClass() ){
- return false;
- } else {
- RatNum tmp = (RatNum)r;
- return(tmp.getNumerator() == numerator && tmp.getDenominator() == denominator);
- }
- }
- /**
- * Method for comparing two RatNum objects, to determine whether the input RatNum is smaller that its argument r.
- * @param r, the RatNum object to compare with.
- * @return a boolean, true if input RatNum is smaller than r.
- */
- public boolean lessThan(RatNum r) {
- return (r.toDouble() > toDouble());
- }
- /**
- * Method for calculating the greatest common divisor (GCD) of two integers.
- * @param a, integer for which the GCD is to be found.
- * @param b, integer for which the GCD is to be found -
- * @return an integer, the GCD.
- * @throws IllegalArgumentException is thrown if a and b are both 0.
- */
- public static int gcd(int a, int b) {
- a = Math.abs(a);
- b = Math.abs(b);
- if (a == 0 && b == 0) {
- IllegalArgumentException e = new IllegalArgumentException();
- throw e;
- } else if (b == 0) {
- return a;
- } else {
- if (a%b == 0) {
- return b;
- } else {
- return(gcd(b,a%b));
- }
- }
- }
- /**
- * Method for parsing string input.
- * Reads string input. If input is valid, method will return a RatNum object.
- * @param s, a string with input.
- * @return a RatNum object, if input is valid.
- * @throws NumberFormatException if input is invalid.
- */
- public static RatNum parse(String s){
- int slash = -1; // The initial value of slash is set to -1 to handle rational number without '/'
- int a = 1;
- int b = 1;
- int slashCounter = 0;
- for(int i = 0; i < s.length(); i++) {
- if(s.charAt(i) == '/'){
- slash = i;
- slashCounter++;
- if(slashCounter > 1) { // To check for silly input
- NumberFormatException e = new NumberFormatException();
- throw e;
- }
- } else if (Character.isDigit(s.charAt(i)) == false && s.charAt(i) != '-') {
- NumberFormatException e = new NumberFormatException();
- throw e;
- }
- }
- if (slash == -1) {
- a = Integer.parseInt(s);
- } else {
- a = Integer.parseInt(s.substring(0,slash));
- b = Integer.parseInt(s.substring(slash+1, s.length()));
- }
- return new RatNum(a,b);
- }
- /**
- * Method for evaluating string input containing RatNum-compliant rational numbers.
- * Uses previous methods for handling addition, subtraction, multiplication, division and comparing.
- * @param str, a string containing input to be evaluated.
- * @return string, containing the calculated RatNum.
- */
- public static String evalExpr(String str){
- //PARSE TWO RATIONAL NUMBERS//
- int endFirstRat = -1;
- int startSecondRat = -1;
- int endSecondRat = -1;
- boolean twoRats = false;
- if(str.charAt(0) == '-' || Character.isDigit(str.charAt(0))){
- for(int i = 1; i < str.length(); i++){
- if(endFirstRat == -1 && str.charAt(i) == ' ' && Character.isDigit(str.charAt(i-1))){
- endFirstRat = i; //Finds the end of the first Rat
- //System.out.println("First: "+i+" substring: "+str.substring(0, endFirstRat));
- } else if(endFirstRat != -1 && startSecondRat == -1 && (Character.isDigit(str.charAt(i)) || (str.charAt(i) == '-') && Character.isDigit(str.charAt(i+1)) )){ //The second number starts here
- startSecondRat = i; //Finds the start of the second Rat
- //System.out.println("Second: "+i+" substring: "+str.substring(startSecondRat));
- } else if(endFirstRat != -1 && startSecondRat != -1 && endSecondRat == -1 && Character.isDigit(str.charAt(i-1)) && str.charAt(i) == ' '){
- endSecondRat = i; //Finds the end of the second Rat (if the string continues after the second Rat)
- twoRats = true;
- } else if(twoRats && (Character.isDigit(str.charAt(i)) || str.charAt(i) == '-')){ //Checks if there are more than two Rats
- return "evalExpr error(1): in RatNum expression, too many or too few terms";
- }
- }
- if(endSecondRat == -1) endSecondRat = str.length(); //Unnecessary code if it's declared as str.length() instead
- if(endFirstRat == -1 || startSecondRat == -1){ //If the first Rat never ends or if the second Rat never starts
- return "evalExpr error(1): in RatNum expression, too many or too few terms";
- } else { //Two substrings have been found by this point
- int slashCounter = 0; //Starts checking if the first Rat is valid
- int slashPosRat1 = -1; //Stores the position of the /
- int slashPosRat2 = -1;
- for(int i = 1; i < endFirstRat; i++){ //Starts at 1 to avoid index out of bounds; shouldn't affect the program
- if((str.charAt(i) == '-' && str.charAt(i-1) != '/') || (!Character.isDigit(str.charAt(i)) && str.charAt(i) != '-' && str.charAt(i) != '/')){
- return "evalExpr error(4): NumberFormatException: "; //Finds invalid Rats, e.g. 3-3/5,
- }
- if(str.charAt(i) == '/' && Character.isDigit(str.charAt(i-1))){
- slashCounter++;
- slashPosRat1 = i;
- if(slashCounter > 1) return "evalExpr error(4): NumberFormatException: ";
- }else if(str.charAt(i) == '/' && !Character.isDigit(str.charAt(i-1))){ //Checks if the character before the / is a digit
- return "evalExpr error(4): NumberFormatException: ";
- }
- }
- slashCounter = 0; //Resets the slash counter and starts checking the second Rat
- for(int i = startSecondRat+1; i < endSecondRat; i++){ //Already knows the first character is valid, so it gets skipped
- if((str.charAt(i) == '-' && str.charAt(i-1) != '/') || (!Character.isDigit(str.charAt(i)) && str.charAt(i) != '-' && str.charAt(i) != '/')){
- return "evalExpr error(4): NumberFormatException: ";
- }
- if(str.charAt(i) == '/'){
- slashCounter++;
- slashPosRat2 = i;
- //System.out.println(slashPosRat2);
- if(slashCounter > 1) return "evalExpr error(4): NumberFormatException: ";
- }else if(str.charAt(i) == '/' && !Character.isDigit(str.charAt(i-1))){ //Checks if the character before the / is a digit
- return "evalExpr error(4): NumberFormatException: ";
- }
- if(!Character.isDigit(str.charAt(endSecondRat-1))){ //Checks if the last character in the second Rat is a digit
- return "evalExpr error(4): NumberFormatException: ";
- }
- }
- if(slashPosRat1 != -1){ //Checks if the denominator in the first Rat is 0
- if(Integer.parseInt(str.substring(slashPosRat1+1, endFirstRat)) == 0){
- //System.out.println(str.substring(slashPosRat1+1, endFirstRat));
- return "evalExpr error(4): NumberFormatException: Denominator = 0";
- }
- }
- if(slashPosRat2 != -1){ //Checks if the denominator in the second Rat is 0
- if(Integer.parseInt(str.substring(slashPosRat2+1, endSecondRat)) == 0){
- //System.out.println(str.substring(slashPosRat2+1, endSecondRat));
- return "evalExpr error(4): NumberFormatException: Denominator = 0";
- }
- }
- }
- } else return "evalExpr error(4): NumberFormatException: ";
- //PARSE THE OPERATOR//
- String operator = str.substring(endFirstRat, startSecondRat);
- //System.out.println(operator);
- //System.out.println("we're here");
- RatNum firstRat = new RatNum(str.substring(0, endFirstRat));
- //System.out.println(startSecondRat);
- //System.out.println(endSecondRat);
- RatNum secondRat = new RatNum(str.substring(startSecondRat, endSecondRat));
- //System.out.println(firstRat+operator+secondRat);
- //ACTIONS, BARRING ANY ERRORS
- if(operator.equals(" + ")) return ""+firstRat.add(secondRat);
- else if(operator.equals(" - ")) return ""+firstRat.sub(secondRat);
- else if(operator.equals(" * ")) return ""+firstRat.mul(secondRat);
- else if(operator.equals(" / ") && secondRat.toDouble() != 0.0) return ""+firstRat.div(secondRat);
- else if(operator.equals(" / ") && secondRat.toDouble() == 0.0) return "evalExpr error(4): NumberFormatException: Denominator = 0";
- else if(operator.equals(" < ")) return ""+firstRat.lessThan(secondRat);
- else if(operator.equals(" = ")) return ""+firstRat.equals(secondRat);
- else return "evalExpr error(2): operator wrong or missing";
- }
- /*
- public static String evalExpr(String str){
- int spaceCounter = 0;
- int operatorPos = -1;
- int firstSpace = -1;
- int secondSpace = -1;
- int numOfNumerators = 0;
- if (Character.isDigit(str.charAt(0))) {
- numOfNumerators++;
- } else if (str.charAt(0) != '-') {
- return "evalExpr error(4): NumberFormatException: ";
- }
- for (int i = 0; i < str.length(); i++) { // Counts the number of terms
- if (Character.isDigit(str.charAt(i)) && i != 0 && ((str.charAt(i-1) == '-' && str.charAt(i-2) != '/') || str.charAt(i-1) != '/') && (!Character.isDigit(str.charAt(i-1)) || str.charAt(i-1) == '-')) {
- numOfNumerators++;
- System.out.println(numOfNumerators);
- }
- }
- if (numOfNumerators != 2) { //TODO: Change the number of terms to two
- return "evalExpr error(1) in ratNum expression, too few or too many terms";
- }
- for (int i = 0; i < str.length(); i++) {
- if (str.charAt(i) == ' ') {
- spaceCounter++;
- if (spaceCounter == 1){
- firstSpace = i;
- } else if (spaceCounter == 2){
- secondSpace = i;
- operatorPos = i-1;
- } else if (spaceCounter > 2){
- return "evalExpr error(5): Unknown error";
- }
- }
- }
- if (secondSpace - firstSpace != 2) {
- return "evalExpr error(2): operator wrong or missing";
- }
- if (spaceCounter == 0) {
- return "evalExpr error(5): Unknown error";
- }
- if (str.charAt(operatorPos) != '/') {
- int slashCounter = 0;
- for (int i = 0; i < str.length(); i++) {
- if (str.charAt(i) == '/') {
- slashCounter++;
- if (slashCounter > 2) {
- return ("evalExpr error(4): NumberFormatException: ");//+ e.getMessage());
- }
- }
- }
- }
- if (str.charAt(operatorPos) == '/') {
- int slashCounter = 0;
- for (int i = 0; i < str.length(); i++) {
- if (str.charAt(i) == '/') {
- slashCounter++;
- if (slashCounter > 3) {
- return ("evalExpr error(4): NumberFormatException: ");//+ e.getMessage());
- }
- }
- }
- String first = str.substring(0,firstSpace);
- String second = str.substring(secondSpace+1,str.length());
- RatNum firstRN = new RatNum(first);
- RatNum secondRN = new RatNum(second);
- if (secondRN.getNumerator() == 0){
- return "evalExpr error(4): NumberFormatException";
- } else {
- return ""+firstRN.div(secondRN);
- }
- } else if (str.charAt(operatorPos) == '*') {
- RatNum firstRN = new RatNum(str.substring(0,firstSpace));
- RatNum secondRN = new RatNum(str.substring(secondSpace+1,str.length()));
- return ""+firstRN.mul(secondRN);
- } else if (str.charAt(operatorPos) == '+') {
- RatNum firstRN = new RatNum(str.substring(0,firstSpace));
- RatNum secondRN = new RatNum(str.substring(secondSpace+1,str.length()));
- return ""+firstRN.add(secondRN);
- } else if (str.charAt(operatorPos) == '-') {
- RatNum firstRN = new RatNum(str.substring(0,firstSpace));
- RatNum secondRN = new RatNum(str.substring(secondSpace+1,str.length()));
- return ""+firstRN.sub(secondRN);
- } else if (str.charAt(operatorPos) == '<') {
- RatNum firstRN = new RatNum(str.substring(0,firstSpace));
- RatNum secondRN = new RatNum(str.substring(secondSpace+1,str.length()));
- return ""+firstRN.lessThan(secondRN);
- } else if (str.charAt(operatorPos) == '=') {
- RatNum firstRN = new RatNum(str.substring(0,firstSpace));
- RatNum secondRN = new RatNum(str.substring(secondSpace+1,str.length()));
- return ""+firstRN.equals(secondRN);
- } else {
- return "evalExpr error(2): operator wrong or missing";
- }
- }
- */
- public static void main(String[] args) {
- System.out.println(evalExpr("5 + 7/0"));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement