Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Background Classes are java constructs, among other properties, that allow the i

ID: 3860365 • Letter: B

Question

Background

Classes are java constructs, among other properties, that allow the implementation of user defined data types.

Assignment

Create two classes one named Rational to represent rational numbers and their operations: sum, subtraction, product, division, equality, and less that; and one class named RUPolynomial to represent polynomial over the real numbers with one indeterminate and their operations: sum, subtraction, product, division, and equality.

As noted in class we can use two integers to represent a rational number, but this representation might no be fully reduced:

10 35 = 5 7

use the Euclidean algorithm to reduce every rational number.

For the polynomial class, use and array-based representation to store the coefficients. Every class should have a toString() method to convert the object into a humanreadable string of characters.

To test each class method, randomly generate two files, rationals.txt and polynomials.txt respectively, with the following structure:

• rationals.txt has 12 lines, every line consists of two decimal integers separated by a blank space (numerator, and denominator respectively). Select each pair of lines consecutively to test for every rational number operator (a total of 6).

• polynomials.txt has 20 lines, to represent 10 polynomials, (a) non-negative degree and (b) real coefficients separated by a blank space. Select each 4 lines to test consecutively for every polynomial operator.

Finally, store in two files, rational results.txt and polynomial results.txt human readable versions of each test. For example, the test of rational division could be produce a string of the form:

“(3/4) ÷ (5/3) = (9/20)”

Explanation / Answer

Rational.java:

public class Rational {

private int num; // the numerator

private int den; // the denominator

public Rational(int numerator, int denominator) {

// if den is 0

if (denominator == 0) {

throw new RuntimeException("Denominator is zero");

}

den = denominator;

num = numerator;

// always keep negative sign with numerator

if (den < 0) {

den = -den;

num = -num;

}

simplify();

}

public int getNum() {

return num;

}

public int getDen() {

return den;

}

public String toString() {

if (den == 1)

return "(" + num + ")";

else

return "(" + num + "/" + den + ")";

}

public void simplify() {

int g = gcd(num, den);

num = num / g;

den = den / g;

}

public Rational plus(Rational b) {

Rational a = this;

Rational s = new Rational((a.num * b.den + b.num * a.den), (a.den * b.den));

return s;

}

public Rational minus(Rational b) {

Rational a = this;

Rational s = new Rational((a.num * b.den - b.num * a.den), (a.den * b.den));

return s;

}

public Rational multiply(Rational b) {

Rational a = this;

Rational s = new Rational((a.num * b.num), (a.den * b.den));

return s;

}

public Rational divide(Rational b) {

Rational a = this;

Rational s = new Rational((a.num * b.den), (a.den * b.num));

return s;

}

public boolean equals(Rational b) {

Rational a = this;

return (a.num == b.num) && (a.den == b.den);

}

public boolean lessThat(Rational b) {

Rational a = this;

return (a.num * b.den) < (a.den * b.num);

}

// to find GCD of 2 numbers

private int gcd(int m, int n) {

if (m < 0)

m = -m;

if (n < 0)

n = -n;

if (0 == n)

return m;

else

return gcd(n, m % n);

}

}

Polynomial.java:

public class Polynomial {

class PolyNode {

int coeff;

int degree;

PolyNode next;

public PolyNode(int coeff, int degree) {

this.coeff = coeff;

this.degree = degree;

}

}

private PolyNode head; // points to the first Node of a Polynomial

public Polynomial() // DO NOT MODIFY THIS CONSTRUCTOR

{

head = null;

}

public Polynomial(Polynomial p) // a "copy" constructor

{

// get the node of list

PolyNode n = p.head;

while (n != null) {

// when we add, it automatically makes the element head, if there is

// only element

addTerm(n.coeff, n.degree);

// go to next element

n = n.next;

}

}

/**

* Creates a new Term and Node containing it and inserts it in its proper

* place in this Polynomial (i.e. in ascending order by exponent)

*/

public void addTerm(int coeff, int degree) {

if(coeff == 0)

return;

// create node

PolyNode n = new PolyNode(coeff, degree);

// if it is the first element

if (head == null) {

head = n;

} else {

// if it has same exponent as head

if (head.degree == degree) {

head.coeff = (head.coeff + coeff);

return;

} else if (head.degree < degree) {

// it need to be inserted before head

n.next = head;

head = n;

return;

}

// loop like p will be the previous node, and we will be comparing

// p.next inside

// keep previous node information is required as we need to add this

// node in between

PolyNode p = head;

while (p.next != null) {

if (degree == p.degree) {

// if same exponent term is there

p.coeff = (p.coeff + coeff);

return;

} else if (degree > p.next.degree) {

// loop till we get some lower exponent position

n.next = p.next;

p.next = n;

return;

}

// move to next

p = p.next;

}

if(p.degree == degree) {

p.coeff = (p.coeff + coeff);

return;

}

// add to the last

p.next = n;

}

}

String getTerm(int coefficient, int exponent) {

String s = "+";

if(coefficient < 0) {

s = "";

}

if (coefficient == 1 && exponent == 1)

return s + "x";

else if (exponent == 0)

return s + String.valueOf(coefficient);

else if (coefficient == 1)

return s + "x^" + String.valueOf(exponent);

else if (exponent == 1)

return s + String.valueOf(coefficient) + "x";

else

return s + String.valueOf(coefficient) + "x^"

+ String.valueOf(exponent);

}

/**

* Returns a polynomial as a String in this form: x + 3x^2 + 7x^3 + x^5

*/

public String toString() {

String s = "";

PolyNode node = head;

String seperator = "";

// for each term, do add

while (node != null) {

s += seperator + getTerm(node.coeff, node.degree);

node = node.next;

seperator = " ";

}

return "(" + s + ")";

}

/**

* Multiply this Polynomial by another Polynomial

*/

public Polynomial multiply(Polynomial p) {

Polynomial result = new Polynomial();

PolyNode p1 = head;

// traverse for each term of p1

while (p1 != null) {

PolyNode p2 = p.head;

// traverse for each term of p2

while (p2 != null) {

// add the new term to result polynomial

result.addTerm(p1.coeff * p2.coeff, p1.degree + p2.degree);

// advance p2

p2 = p2.next;

}

// advance p1

p1 = p1.next;

}

return result;

}

/**

* Add this Polynomial and another Polynomial

*/

public Polynomial plus(Polynomial p) {

// create a copy of original polynomial

// we will add new node to directly this.

Polynomial result = new Polynomial(this);

PolyNode p1 = p.head;

// our add Term method, add the coefficients, if exponent is same,

// else it will create a new term

while (p1 != null) {

result.addTerm(p1.coeff, p1.degree);

p1 = p1.next;

}

return result;

}

/**

* subtract this Polynomial and another Polynomial

*/

public Polynomial minus(Polynomial p) {

// create a copy of original polynomial

// we will add new node to directly this.

Polynomial result = new Polynomial(this);

PolyNode p1 = p.head;

// our add Term method, add the coefficients, if exponent is same,

// else it will create a new term

// we are changing the sign of coefficient here, so that it can be added

while (p1 != null) {

result.addTerm(-1 * p1.coeff, p1.degree);

p1 = p1.next;

}

return result;

}

public boolean equals(Polynomial p) {

PolyNode p1 = this.head;

PolyNode p2 = p.head;

while (p1 != null || p2 != null) {

if((p1.coeff != p2.coeff) || (p1.degree != p2.degree)) {

return false;

}

p2 = p2.next;

p1 = p1.next;

}

return true;

}

}

Demo.java:

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.util.Scanner;

public class Demo {

public static Rational getRational(Scanner s) {

int a = s.nextInt();

int b = s.nextInt();

return new Rational(a, b);

}

private static Polynomial getPolynomial(Scanner polynomialFile) {

Polynomial p = new Polynomial();

int degree = polynomialFile.nextInt();

for(int i=degree; i>=0; i--) {

p.addTerm(polynomialFile.nextInt() , i);

}

return p;

}

public static void main(String[] args) throws IOException {

// read rationals.txt:

Scanner rationalFile = new Scanner(new FileReader("rationals.txt"));

BufferedWriter rationalOutputFile = new BufferedWriter(new FileWriter("rational results.txt"));

Rational a = getRational(rationalFile);

Rational b = getRational(rationalFile);

rationalOutputFile.append(a.toString() + " + " + b.toString() + " = " + a.plus(b).toString() + " ");

a = getRational(rationalFile);

b = getRational(rationalFile);

rationalOutputFile.append(a.toString() + " - " + b.toString() + " = " + a.minus(b).toString() + " ");

a = getRational(rationalFile);

b = getRational(rationalFile);

rationalOutputFile.append(a.toString() + " * " + b.toString() + " = " + a.multiply(b).toString() + " ");

a = getRational(rationalFile);

b = getRational(rationalFile);

rationalOutputFile.append(a.toString() + " / " + b.toString() + " = " + a.divide(b).toString() + " ");

a = getRational(rationalFile);

b = getRational(rationalFile);

rationalOutputFile.append(a.toString() + " == " + b.toString() + " : " + a.equals(b) + " ");

a = getRational(rationalFile);

b = getRational(rationalFile);

rationalOutputFile.append(a.toString() + " < " + b.toString() + " : " + a.lessThat(b) + " ");

rationalFile.close();

rationalOutputFile.close();

// read polynomials.txt:

Scanner polynomialFile = new Scanner(new FileReader("polynomials.txt"));

BufferedWriter polynomialOutputFile = new BufferedWriter(new FileWriter("polynomial results.txt"));

Polynomial x = getPolynomial(polynomialFile);

Polynomial y = getPolynomial(polynomialFile);

polynomialOutputFile.append(x.toString() + " + " + y.toString() + " = " + x.plus(y).toString() + " ");

x = getPolynomial(polynomialFile);

y = getPolynomial(polynomialFile);

polynomialOutputFile.append(x.toString() + " - " + y.toString() + " = " + x.minus(y).toString() + " ");

x = getPolynomial(polynomialFile);

y = getPolynomial(polynomialFile);

polynomialOutputFile.append(x.toString() + " * " + y.toString() + " = " + x.multiply(y).toString() + " ");

x = getPolynomial(polynomialFile);

y = getPolynomial(polynomialFile);

polynomialOutputFile.append(x.toString() + " == " + y.toString() + " : " + x.equals(b) + " ");

x = getPolynomial(polynomialFile);

y = getPolynomial(polynomialFile);

polynomialOutputFile.append(x.toString() + " == " + y.toString() + " : " + a.equals(b) + " ");

polynomialFile.close();

polynomialOutputFile.close();

System.out.println("Program completed successfully!!");

}

}

rationals.txt:

10 4
5 6
5 3
3 9
1 5
5 3
3 6
7 9
3 5
5 19
12 4
11 7

polynomials.txt:
2
1 2 3
2
0 2 1
2
3 2 1
4
3 5 6 0 2
1
2 3
0
2
1
5 6
3
6 4 0 2
3
1 0 1 1
2
2 5 2



Output:
polynomials result.txt:

(+x^2 +2x +3) + (+2x +1) = (+x^2 +4x +4)
(+3x^2 +2x +1) - (+3x^4 +5x^3 +6x^2 +2) = (-3x^4 -5x^3 -3x^2 +2x -1)
(+2x +3) * (+2) = (+4x +6)
(+5x +6) == (+6x^3 +4x^2 +2) : false
(+x^3 +x +1) == (+2x^2 +5x +2) : false

rational result.txt:
(5/2) + (5/6) = (10/3)
(5/3) - (1/3) = (4/3)
(1/5) * (5/3) = (1/3)
(1/2) / (7/9) = (9/14)
(3/5) == (5/19) : false
(3) < (11/7) : false

i am not sure on how to divide the polynomials, as it is not always possible to get the complete division of one polynoial by another.. rest code i have implemented.

Please keep the input files in the same directory as java files.