It seems that this calculator works for all other cases, except cases like this:
(2*3^4)
It does not return 162, instead, it returns 0.0.
I identified that the error must be from the method public static double operation, since the default return statement is 0.0
Here is the code:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class StackC<Item> implements Stack<Item> {
private Item[] a; // array of items
private int N; // number of elements on stack
public StackC() {
a = (Item[]) new Object[2];
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
private void resize(int capacity) {
assert capacity >= N;
Item[] temp = (Item[]) new Object[capacity];
for (int i = 0; i < N; i++) {
temp[i] = a[i];
}
a = temp;
}
public void push(Item item) {
if (N == a.length) resize(2*a.length); // double size of array if necessary
a[N++] = item; // add item
}
public Item pop() {
if (isEmpty())
throw new NoSuchElementException("Stack underflow");
Item item = a[N-1];
a[N-1] = null; // to avoid loitering
N--;
// shrink size of array if necessary
if (N > 0 && N == a.length/4)
resize(a.length/2);
return item;
}
public Item peek() {
if (isEmpty())
throw new NoSuchElementException("Stack underflow");
return a[N-1];
}
public Iterator<Item> iterator() {
return new ReverseArrayIterator();
}
private class ReverseArrayIterator implements Iterator<Item> {
private int i;
public ReverseArrayIterator() {
i = N;
}
public boolean hasNext() {
return i > 0;
}
public void remove() {
throw new UnsupportedOperationException();
}
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
return a[--i];
}
}
//---------------------------------------------------------------------
public static void main(String[] args) {
StackC<String> Operator = new StackC<String>();
StackC<Double> Values = new StackC<Double>();
while (!StdIn.isEmpty()) {
String token = StdIn.readString();
try {
Double x = Double.parseDouble(token);
Values.push(x);
}
catch(NumberFormatException nFE) {
}
if (token.equals("("))
Operator.push(token);
if (token.equals(")"))
{
if (Operator.peek() != "(")
{
String type = Operator.pop();
double b = Values.pop();
double a = Values.pop();
Values.push(operation(type,a,b));
}
Operator.pop();
}
if(token.equals("*") || token.equals("+") || token.equals("/") || token.equals("-") || token.equals("^") )
{
if(!Operator.isEmpty())
{
String prev = Operator.peek();
int x = comparePrecedence(token, Operator.peek()); // You need to compare precedence first
if(x == -1 || x == 0)
{
String type = Operator.pop();
double b = Values.pop();
double a = Values.pop();
Values.push(operation(type,a,b));
}
}
Operator.push(token);
}
}
while(!Operator.isEmpty())
{
String prev = Operator.peek();
String type = Operator.pop();
double b = Values.pop();
double a = Values.pop();
Values.push(operation(type,a,b));
}
System.out.println(Values.pop());
}
public static double operation(String operator, double a, double b) {
if (operator.equals("+"))
return a + b;
else if (operator.equals("-"))
return a - b;
else if (operator.equals("*"))
return a * b;
else if (operator.equals("/"))
return a / b;
else if (operator.equals("^"))
return Math.pow(a,b);
return 0.0;
}
public static int comparePrecedence(String x, String y)
{
int val1 = 0;
int val2 = 0;
if(x.equals("-"))
val1 = 0;
if(y.equals("-"))
val2 = 0;
if(x.equals("+"))
val1 = 1;
if(y.equals("+"))
val2 = 1;
if(x.equals("/"))
val1 = 2;
if(y.equals("/"))
val2 = 2;
if(x.equals("*"))
val1 = 3;
if(y.equals("*"))
val2 = 3;
if(x.equals("^"))
val1 = 4;
if(y.equals("^"))
val2 = 4;
if(val1 > val2)
return 1;
else if(val2 > val1)
return -1;
else
return 0;
}
}
Everything above the dotted line was given via the professor, and is not the problem for the code.
StdIn is simply a method that reads inputs.
Related
I almost have a working Huffman algorithm but I'm having trouble figuring out how to implement it / or make it work together with the Code class. It is my method generateHuffmanCode that needs to be working with the Code class.
I don't know if I'm missing something or if I'm just using the wrong approach.
My Huffman class
package code;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import code.Code;
import application.TCode;
class Node{
Character ch;
Integer freq;
Node left = null, right = null;
Node(Character ch, Integer freq){
this.ch = ch;
this.freq = freq;
}
public Node (Character ch, Integer freq, Node left, Node right) {
this.ch = ch;
this.freq = freq;
this.left = left;
this.right = right;
}
}
public class Huffman {
public static void encode(Node root, String str, Map<Character, String> huffmanCode) {
if (root == null) {
return;
}
if(isLeaf(root)) {
huffmanCode.put(root.ch, str.length() > 0 ? str : "1");
}
encode(root.left, str + '0', huffmanCode);
encode(root.right, str + '1', huffmanCode);
}
public static int decode(Node root, int index, StringBuilder sb) {
if(root == null) {
return index;
}
index++;
if(isLeaf(root)) {
System.out.println(root.ch);
}
index++;
root = (sb.charAt(index) == '0') ? root.left : root.right;
index = decode(root, index, sb);
return index;
}
public static boolean isLeaf(Node root) {
return root.left == null && root.right == null;
}
public static void generateHuffmanCode(Code c) {
// if(c == null || c.length() == 0) {
// return;
// }
Map<Character, double> freq = new HashMap<>(); // why can't I use a double in Map<Character, double>??
for(char s : probability.toCharArry()){
freq.put(s, freq.getOrDefault(s, 0) + 1);
}
PriorityQueue<Node> pq;
pq = new PriorityQueue<>(Comparator.comparingInt(l -> l.freq));
for(var entry: freq.entrySet()) {
pq.add(new Node(entry.getKey(), entry.getValue()));
}
while (pq.size() != 1) {
Node left = pq.poll();
Node right = pq.poll();
int sum = left.freq + right.freq;
pq.add(new Node(null, sum, left, right));
}
Node root = pq.peek();
Map<Character, String> huffmanCode = new HashMap<>();
encode(root, "", huffmanCode);
System.out.println("Huffman Codes are: " + huffmanCode);
System.out.println(probability);
StringBuilder sb = new StringBuilder();
for(char s : probability.toCharArray()) {
sb.append(huffmanCode.get(s));
}
System.out.println("The endcoded String is: " + sb);
System.out.println("The decoded String is: " );
if (isLeaf(root)) {
while (root.freq-- > 0) {
System.out.println(root.ch);
}
} else {
int index = -1;
while(index < sb.length() - 1) {
index = decode(root, index, sb);
}
}
}
public static void main(String[] args) {
generateHuffmanCode(Code probability);
// Code.CodeItem[] ci = {
// new Code.CodeItem("A", 0.12),
// new Code.CodeItem("B", 0.19),
// new Code.CodeItem("C", 0.40),
// new Code.CodeItem("D", 0.13),
// new Code.CodeItem("E", 0.16)
// };
// Code c = new Code(ci);
}
}
And my Code class
package code;
public final class Code {
private CodeItem[] item = null;
public final static class CodeItem {
private String symbol;
private double probability; // the sum of all probabilities must be approx. 1
private String encoding; // a string containing only '0' and '1'
public CodeItem(String symbol, double probability, String encoding) {
this.symbol = symbol.trim();
this.probability = probability;
this.encoding = encoding;
if (!is01() || this.symbol == null || this.symbol.length() == 0 || this.probability < 0.0)
throw new IllegalArgumentException();
}
public CodeItem(String symbol, double probability) {
this(symbol, probability, null);
}
public String getSymbol() {
return symbol;
}
public double getProbability() {
return probability;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public boolean is01() {
if (encoding == null || encoding.length() == 0)
return true;
for (int i = 0; i < encoding.length(); ++i)
if ("01".indexOf(encoding.charAt(i)) < 0)
return false;
return true;
}
}
public Code(CodeItem[] codeItem) {
if (codeItem == null || codeItem.length == 0)
throw new IllegalArgumentException();
double sum = 0.0;
for (int i = 0; i < codeItem.length; ++i) {
sum += codeItem[i].probability;
if (codeItem[i].probability == 0.0)
throw new IllegalArgumentException();
}
if (Math.abs(sum - 1.0) > 1e-10)
throw new IllegalArgumentException();
item = new CodeItem[codeItem.length];
for (int i = 0; i < codeItem.length; ++i)
item[i] = codeItem[i];
}
public boolean is01() {
for (int i = 0; i < item.length; ++i)
if (!item[i].is01())
return false;
return true;
}
public double entropy() {
double result = 0.0;
for(int i = 0; i < item.length; ++i)
result += item[i].probability * (-Math.log(item[i].probability) / Math.log(2.0));
return result;
}
public double averageWordLength() {
double result = 0.0;
for(int i = 0; i < item.length; ++i)
result += item[i].encoding.length() * item[i].probability;
return result;
}
public boolean isPrefixCode() {
for(int i = 1; i < item.length; ++i)
for(int j = 0; j < i; ++j)
if (item[i].encoding.startsWith(item[j].encoding) || item[j].encoding.startsWith(item[i].encoding))
return false;
return true;
}
public int size() {
return item.length;
}
public CodeItem getAt(int index) {
return item[index];
}
public CodeItem getBySymbol(String symbol) {
for (int i = 0; i < item.length; ++i) {
if (item[i].symbol.equals(symbol))
return item[i];
}
return null;
}
public String toString() {
String result = "";
for(int i = 0; i < item.length; ++i) {
result += item[i].symbol + " (" + item[i].probability + ") ---> " + item[i].encoding + "\n";
}
return result.substring(0, result.length()-1);
}
}
I'm having an issue with one of my methods findLargest(Comparable[ ] arr) in class FindLargest that's meant to return the largest element in an array.
Apparently, in class Lab5Main this method works fine with fractions, but I get a compilation error with dates. In the system print out command, I'm getting this error:
The method findLargest(Comparable[ ]) in the type FindLargest is not applicable for the arguments (MyDate[ ])
Here is the supposed program output:
The largest fraction is 9/4
The latest date is 18/8/2011
My codes are shown below:
public class Lab5Main {
public static void main(String[] args) {
// Fraction
Fraction fractions[] = new Fraction[3];
fractions[0] = new Fraction(1, 2);
fractions[1] = new Fraction(6, 11);
fractions[2] = new Fraction(9, 4);
System.out.println("The largest fraction is " + FindLargest.findLargest(fractions));
// MyDate
MyDate dates[] = new MyDate[3];
dates[0] = new MyDate(1898, 6, 9);
dates[1] = new MyDate(2003, 4, 1);
dates[2] = new MyDate(2011, 8, 18);
System.out.println("The latest date is " + FindLargest.findLargest(dates));
}
}
public class FindLargest {
public static <T extends Comparable<? super T>> T findLargest(T[] arr) {
if (arr.length == 0) {
return null;
}
T max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i].compareTo(max) > 0) {
max = arr[i];
}
}
return max;
}
public class Fraction implements Comparable<Fraction> {
private int num, denom;
public int gcd(int a, int b) {
if (a%b==0) {
return b;
}
return gcd(b, a%b);
}
public void reduce() {
int g = gcd(num, denom);
num = num / g;
denom = denom / g;
}
public Fraction(int n, int d) {
if (n==0) {
d=1;
}
if (d==0) {
n=1;
d=2;
}
if(d<0) {
n=-n;
d=-d;
}
num = n;
denom = d;
reduce();
}
public String toString() {
return num + "/" + denom;
}
#Override
public int compareTo(Fraction f) {
// Fraction f = (Fraction) obj;
if (Math.abs(value() - f.value()) < 0.00001) {
return 0;
}
if (value() > f.value()) {
return 1;
}
return -1;
}
public int compareTo(Object obj) {
Fraction f = (Fraction) obj;
if (Math.abs(value() - f.value()) < 0.00001) {
return 0;
}
if (value() > f.value()) {
return 1;
}
return -1;
}
}
public class MyDate implements Comparable<MyDate> {
private int year, month, day;
public MyDate(int z, int y, int x) {
if (z<1000 || z>3000) {
z = 2000;
}
if (y<1 || y>12) {
y = 1;
}
if (x<1 || x>31) {
x = 1;
}
day = x;
month = y;
year = z;
}
public String toString() {
return day + "/" + month + "/" + year;
}
#Override
public int compareTo (MyDate date){
// MyDate date = (MyDate) obj;
int diffYear = year - date.year;
if (diffYear < 0) {
return -1;
}
else if (diffYear > 0) {
return 1;
}
int diffMonth = month - date.month;
if (diffMonth < 0) {
return -1;
}
else if (diffMonth > 0) {
return 1;
}
int diffDay = day - date.day;
if (diffDay < 0) {
return -1;
}
else if (diffDay > 0) {
return 1;
}
return 0;
}
}
The issue is one of raw-types and generics. Comparable is a generic interface, but you are implementing it with a raw-type and you are using it with raw-types. You should fix that. Something like,
public static <T extends Comparable<? super T>> T findLargest(T[] arr) {
if (arr.length == 0) {
return null;
}
T max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i].compareTo(max) > 0) {
max = arr[i];
}
}
return max;
}
will ensure that you call findLargest with a generic type T that can be compared with itself and all of its' superclasses. You should also change Fraction and MyDate. Something like,
public class Fraction implements Comparable<Fraction> {
// ...
#Override
public int compareTo(Fraction f) {
if (Math.abs(value() - f.value()) < 0.00001) {
return 0;
}
if (value() > f.value()) {
return 1;
}
return -1;
}
}
And MyDate similarly. I would recommend you always use the #Override annotation when you intend to override a method.
The first time I get the collision in put method ie when hasKey returns -1 the rehashing method starts and value that triggered collision goes to doubled array to likely empty slot. But System.out.println(m.get("1000")); gives me null for some keys which means they were lost. I don't understand how they could be lost because there is nothing to override them in keyArray.
import java.util.*;
public class StringMapParallel implements Iterable<String>{
private int nButckets = 2000;
private String[] keyArray = new String[nButckets];
private String[] valueArray = new String[nButckets];
private int numberOfEntries = 0;
public static void main(String[] args) {
StringMapParallel m = new StringMapParallel();
;
for (int i = 0; i < 8000; i++) {
m.put(String.valueOf(i), String.valueOf(i));
}
System.out.println(m.get("1000"));
}
private void rehashing() {
if (numberOfEntries > (int) (0.3 * nButckets)) {
int newBucketsNumber = nButckets * 2;
String[] newKeyArray = new String[newBucketsNumber];
String[] newValueArray = new String[newBucketsNumber];
for (int i = 0; i < keyArray.length; i++) {
if (keyArray[i] != null) {
int index = keyArray[i].hashCode() % newBucketsNumber;
newKeyArray[index] = keyArray[i];
newValueArray[index] = valueArray[keyArray[i].hashCode() % nButckets];
}
}
/*
for (String key: this) {
int index = key.hashCode() % newBucketsNumber;
newKeyArray[index] = key;
if (key == null) System.out.println(key);
newValueArray[index] = valueArray[key.hashCode() % nButckets];
}
*/
keyArray = newKeyArray;
valueArray = newValueArray;
nButckets = newBucketsNumber;
}
}
public void put(String key, String value) {
int index = key.hashCode() % nButckets;
int hasKey = hasKey(index, key);
if (hasKey == 1) {
valueArray[index] = value;
} else if (hasKey == 0){
keyArray[index] = key;
valueArray[index] = value;
numberOfEntries++;
} else {
rehashing();
index = key.hashCode() % nButckets;
keyArray[index] = key;
valueArray[index] = value;
numberOfEntries++;
}
}
public String get(String key) {
int index = key.hashCode() % nButckets;
if (hasKey(index, key) == 1) return valueArray[index];
return null;
}
private int hasKey(int index, String key) {
if (keyArray[index] == null) {
return 0;
} else if (keyArray[index].equals(key)) {
return 1;
} else {
return -1;
}
}
public Iterator<String> iterator(){
Iterator<String> iter = new Iterator<String>() {
private int currentIndex = 0;
private int nEntries = 0;
#Override
public boolean hasNext() {
return nEntries < numberOfEntries && numberOfEntries != 0;
}
#Override
public String next() {
for (int i = currentIndex; i < keyArray.length; i++) {
if (keyArray[i] != null) {
currentIndex = i + 1;
nEntries++;
return keyArray[i];
}
}
return null;
}
};
return iter;
}
}
The value of int index = key.hashCode() % nButckets; in your algorithm for key 1000 and 6357 is same, which is 1423. Hence, the your algorithm overwrites keyArray[1423]=1000 with keyArray[1423]=6357
When you are printing m.get(String.valueOf(1000)), following get() method checks for index as well as key, hence it would return null. Read comment in the code for further explanation.
public String get(String key) {
//System.out.println(key+" "+ key.hashCode());
int index = key.hashCode() % nButckets;
System.out.println(index+"bfb"+hasKey(index, key));
//hasKey(index, key) would return -1, because key[1423] is 6357, and not 1000 as you expected.
if (hasKey(index, key) == 1) return valueArray[index];
return null;
}
private int hasKey(int index, String key) {
//System.out.println(keyArray[index]);
if (keyArray[index] == null) {
return 0;
} else if (keyArray[index].equals(key)) {
return 1;
} else {
return -1;
}
}
I have to create an ADT to read a number of data and calculate the median of those data. The ADT consist in a MIN and a MAX heap.
The MinHeap class takes the numbers greaters or equal than the median.
public class MinHeap {
public double[] data;
public int Size;
public MinHeap(int size) {
data = new double[size];
Size = 0;
}
public double getMinimum(){
return this.data[0];
}
public boolean isEmpty() {
return (Size == 0);
}
private int getParentIndex(int nodeIndex) {
return (nodeIndex - 1) / 2;
}
public void insertu(double value) throws Exception {
if (Size == data.length)
throw new Exception("Heap's underlying storage is overflow");
else {
Size++;
data[Size - 1] = value;
siftUp(Size - 1);
}
}
public void siftUp(int nodeIndex) {
int parentIndex;
double tmp;
if (nodeIndex != 0) {
parentIndex = getParentIndex(nodeIndex);
if (data[parentIndex] > data[nodeIndex]) {
tmp = data[parentIndex];
data[parentIndex] = data[nodeIndex];
data[nodeIndex] = tmp;
siftUp(parentIndex);
}
}
}
}`
The MaxHeapclass takes the numbers that are less or equal than the median.
public class MaxHeap{
public double [] _Heap;
public int _size;
public int tam=0;
public MaxHeap (int a){
_Heap = new double[a];
_size = _Heap.length;
for (int i = _Heap.length / 2 ; i >=0 ; i--) {
tam++;
maxHeapify(i);
}
}
private int parent(int pos)
{ return pos / 2; }
private int leftChild(int pos)
{ return (2 * pos); }
private int rightChild(int pos)
{ return (2 * pos) + 1; }
private void swap(int fpos,int spos) {
double tmp;
tmp = _Heap[fpos];
_Heap[fpos] = _Heap[spos];
_Heap[spos] = tmp;
}
private void maxHeapify (int i) {
int l = leftChild(i), r = rightChild(i), largest;
if(l < _size && _Heap[l] > _Heap[i]) {
tam+=2;
largest = l;
}
else largest = i;
if(r < _size && _Heap[r] > _Heap[largest]) {
largest = r;
tam+=2; }
if (largest != i) {
tam++;
swap(i, largest);
maxHeapify (largest); }
}
protected boolean isEmpty() { return _size == 0; }
protected void deleteMax() {
if (_size > 1) {
tam++;
maxHeapify(0);
double max = _Heap[0];
_size--;
swap(0, _size);
maxHeapify(0); }
else _size = 0;
}
protected double extractMax() {
maxHeapify(0);
return _Heap[0];
}
public void insert(double element)
{
_Heap[++tam] = element;
int current = tam;
while(_Heap[current] > _Heap[parent(current)])
{
swap(current,parent(current));
current = parent(current);
}
}
}`
And the ADT:
`import java.util.InputMismatchException;`
`import java.util.Scanner;`
public class ColaPrioridadMediana {
private MinHeap MIN;
private MaxHeap MAX;
private int size;
public ColaPrioridadMediana(int cap) {
if (cap%2==0){
MIN = new MinHeap(cap/2);
MAX = new MaxHeap(cap/2);
}
else{
MIN = new MinHeap((cap+1)/2);
MAX = new MaxHeap((cap+1)/2);
}
size = MAX.counter + MIN.Size;
}
public void insertar(double x) throws Exception{
if (x <= MAX.extractMax()){
if (MAX.counter > MIN.Size){
double d = MAX.extractMax();
MIN.insertu(d);
MAX.insert(x);
}
else{
MAX.insert(x);
}
}
else{
if (MIN.Size > MAX.counter){
double d = MIN.getMinimum();
MAX.insert(d);
MIN.data[0] = x;
MIN.siftUp(1);
}
else{
MIN.insertu(x);
}
}
}
public int getSize(){
return size;
}
public double getMediana() throws Exception{
if(MAX.counter==MIN.Size){return ((MAX.extractMax()+MIN.getMinimum())/2);}
else{
if (MAX.counter<MIN.Size){return MIN.getMinimum();}
else{return MAX.extractMax();}
}
}
public static void main(String[] args) throws NumberFormatException, Exception{
#SuppressWarnings("resource")
Scanner num=new Scanner(System.in);
ColaPrioridadMediana allNumbers=new ColaPrioridadMediana(10);
while(true){
System.out.print("Number:");
try{
String number=num.nextLine();
double d;
if(!number.isEmpty()){
allNumbers.insertar(Double.parseDouble(number));
}else{
d = allNumbers.getMediana();
System.out.println("The result is " + d);
System.out.println(allNumbers.MAX.extractMax());
System.out.println(allNumbers.MIN.getMinimum());
System.out.println(allNumbers.MAX.counter);
System.out.println(allNumbers.MIN.Size);
for (int i=0;i<allNumbers.MAX._Heap.length;i++){
System.out.println(allNumbers.MAX._Heap[i]);
System.out.println(allNumbers.MIN.data[i]);
}
System.exit(0);
}
}
catch(InputMismatchException e){
System.out.println("Not number");
}
}
}
}`
The MinHeap works, but the MaxHeap don't store any numbers, and prints only 0.0. I'm really stuck in here.
In java, using the Java Standard class PriorityQueue to simulate Max-Min heap is not a bad idea. It will reduce coding significantly.
public class MaxMinHeap{
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((x,y)->(y-x));
private void add(int val) {
if (maxHeap.size() == 0) {
maxHeap.add(val);
} else {
int maxTop = maxHeap.peek();
if (val <= maxTop) {
maxHeap.add(val);
} else {
minHeap.add(val);
}
if (maxHeap.size() - minHeap.size() > 1) {
minHeap.add(maxHeap.poll());
} else if (minHeap.size() - maxHeap.size() > 1) {
maxHeap.add(minHeap.poll());
}
}
}
private double findMedian() {
if(maxHeap.size() > minHeap.size()) {
return maxHeap.peek();
}else if(maxHeap.size() == minHeap.size()) {
return ((double) maxHeap.peek() + minHeap.peek()) / 2;
}else {
return minHeap.peek();
}
}
}
My add method works, however when I create a new SparsePolynomial object (at the bottom of the add method), the value of the newSparePolynomial changes when I debug it and I can't figure out where the extra information is coming from. Can someone help me?
Here is a copy of my code:
import java.util.ArrayList;
public class SparsePolynomial {
private ArrayList<Polynomial> polynomialarraylist = new ArrayList<Polynomial>();
/**
* Constructor to get values of an arraylist of integers
* #param arraylist that contains the integer values used for the polynomials
*/
public SparsePolynomial(ArrayList<Integer> arrayList)
{
//MODIFIDED: polynomialarraylist
//EFFECT: constructs the arraylist of polynomials based off the arraylist of integers
insertIntoPolynomialArray(arrayList);
}
/**
* Converts the elements of the integer array into polynomials
* #param arrayList that contains the polynomials contents
*/
private void insertIntoPolynomialArray(ArrayList<Integer> arrayList)
{
//MODIFIED: polynomialarray
//EFFECT: inputs the values of the arrayList into the polynomial array based on the position of the digits
for(int i = 0; i < arrayList.size(); i++)
{
Polynomial polynomial = new Polynomial(arrayList.get(i), arrayList.get(i+1));
polynomialarraylist.add(polynomial);
System.out.println("coef" + arrayList.get(i));
System.out.println("degree" + arrayList.get(i+1));
i++;
}
}
/**
*
*/
#Override
public String toString()
{
String result = "";
sort();
if (getDegree(0) == 0)
return "" + getCoefficient(0);
if (getDegree(0) == 1)
return getCoefficient(0) + "x + " + getCoefficient(0);
result = getCoefficient(0) + "x^" + getDegree(0);
for (int j = 1; j < polynomialarraylist.size(); j++)
{
if(j > polynomialarraylist.size())
{
break;
}
if
(getCoefficient(j) == 0) continue;
else if
(getCoefficient(j) > 0) result = result+ " + " + ( getCoefficient(j));
else if
(getCoefficient(j) < 0) result = result+ " - " + (-getCoefficient(j));
if(getDegree(j) == 1) result = result + "x";
else if (getDegree(j) > 1) result = result + "x^" + getDegree(j);
}
return result;
}
/**
* Sorts array
* #param array to sort
*/
private void sort()
{
ArrayList<Polynomial> temp = polynomialarraylist;
ArrayList<Polynomial> temp2 = new ArrayList<Polynomial>();
int polydegreemain = polynomialarraylist.get(0).degree();
temp2.add(polynomialarraylist.get(0));
for(int i = 1; i < polynomialarraylist.size(); i++)
{
if(i > polynomialarraylist.size())
{
break;
}
int polydegreesecondary = polynomialarraylist.get(i).degree();
if(polydegreemain < polydegreesecondary)
{
temp.set(i-1, polynomialarraylist.get(i));
temp.set(i, temp2.get(0));
}
}
polynomialarraylist = temp;
}
/**
* Makes object hashable
*/
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime
* result
+ ((polynomialarraylist == null) ? 0 : polynomialarraylist
.hashCode());
return result;
}
/**
* Checks for equality of two objects
*/
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SparsePolynomial other = (SparsePolynomial) obj;
if (polynomialarraylist == null) {
if (other.polynomialarraylist != null)
return false;
} else if (!polynomialarraylist.equals(other.polynomialarraylist))
return false;
return true;
}
public boolean equals(SparsePolynomial Sparse)
{
if(this == Sparse)
{
return true;
}
else
{
return false;
}
}
public SparsePolynomial add(SparsePolynomial other)
{
ArrayList<Polynomial> thisPolynomial = createPolynomial();
SparsePolynomial newSparsePolynomial;
ArrayList<Polynomial> otherPolynomial = other.createPolynomial();
Polynomial oldsum = new Polynomial();
Polynomial newsum = new Polynomial();
for(int i = 0; i < thisPolynomial.size();i++)
{
if(thisPolynomial.size() == 1)
{
newsum = thisPolynomial.get(i);
oldsum = newsum;
break;
}
if(i == 0)
{
newsum = thisPolynomial.get(i).add(thisPolynomial.get(i+1));
oldsum = newsum;
i++;
}
else
{
newsum = oldsum.add(thisPolynomial.get(i));
oldsum = newsum;
}
}
for(int i = 0; i < otherPolynomial.size(); i++)
{
newsum = oldsum.add(otherPolynomial.get(i));
oldsum = newsum;
}
ArrayList<Integer> ints = new ArrayList<Integer>();
for(int i = 0; i < oldsum.degree()+1; i++)
{
ints.add(oldsum.coefficient(i));
ints.add(i);
}
newSparsePolynomial = new SparsePolynomial(ints);
return newSparsePolynomial;
}
public SparsePolynomial subtract(SparsePolynomial other)
{
ArrayList<Polynomial> thisPolynomial = createPolynomial();
ArrayList<Polynomial> otherPolynomial = other.createPolynomial();
Polynomial olddifference = new Polynomial();
Polynomial newdifference = new Polynomial();
for(int i = 0; i < thisPolynomial.size()+1;i++)
{
if(i == 0)
{
newdifference = thisPolynomial.get(i).subtract(thisPolynomial.get(i+1));
olddifference = newdifference;
i++;
}
else
{
newdifference = olddifference.subtract(thisPolynomial.get(i));
olddifference = newdifference;
}
}
for(int i = 0; i < otherPolynomial.size(); i++)
{
newdifference = olddifference.add(otherPolynomial.get(i));
olddifference = newdifference;
}
ArrayList<Polynomial> polyarray = createArrayListOfPolynomialsFromPolynomials(olddifference);
ArrayList<Integer> ints = new ArrayList<Integer>();
for(int i = 0; i < polyarray.size(); i++)
{
ints.add(polyarray.get(i).coefficient(polyarray.get(i).degree()));
ints.add(polyarray.get(i).degree());
}
SparsePolynomial newSparsePolynomial = new SparsePolynomial(ints);
return newSparsePolynomial;
}
private int getDegree(int index)
{
int degree;
degree = polynomialarraylist.get(index).degree();
return degree;
}
private int getCoefficient(int index)
{
int coefficient;
coefficient = polynomialarraylist.get(index).coefficient(polynomialarraylist.get(index).degree());
return coefficient;
}
private ArrayList<Polynomial> createPolynomial()
{
Polynomial polynomial = null;
ArrayList<Polynomial> polynomialArray = new ArrayList<Polynomial>();
for(int i = 0; i < polynomialarraylist.size(); i++)
{
polynomial = new Polynomial(getCoefficient(i), getDegree(i));
polynomialArray.add(polynomial);
}
return polynomialArray;
}
Polynomial class
public class Polynomial {
// Overview: ...
private int[] terms;
private int degree;
// Constructors
public Polynomial() {
// Effects: Initializes this to be the zero polynomial
terms = new int[1];
degree = 0;
}
public Polynomial(int constant, int power) {
// Effects: if n < 0 throws IllegalArgumentException else
// initializes this to be the polynomial c*x^n
if(power < 0){
throw new IllegalArgumentException("Polynomial(int, int) constructor");
}
if(constant == 0) {
terms = new int[1];
degree = 0;
return;
}
terms = new int[power+1];
for(int i=0; i<power; i++) {
terms[i] = 0;
}
terms[power] = constant;
degree = power;
}
private Polynomial(int power) {
terms = new int[power+1];
degree = power;
}
// Methods
public int degree() {
// Effects: Returns the degree of this, i.e., the largest exponent
// with a non-zero coefficient. Returns 0 is this is the zero polynomial
return degree;
}
public int coefficient(int degree) {
// Effects: Returns the coefficient of the term of this whose exponent is degree
if(degree < 0 || degree > this.degree) {
return 0;
}
else {
return terms[degree];
}
}
public Polynomial subtract(Polynomial other) throws NullPointerException {
// Effects: if other is null throws a NullPointerException else
// returns the Polynomial this - other
return add(other.minus());
}
public Polynomial minus() {
// Effects: Returns the polynomial - this
Polynomial result = new Polynomial(degree);
for(int i=0; i<=degree; i++) {
result.terms[i] = -this.terms[i];
}
return result;
}
public Polynomial add(Polynomial other) throws NullPointerException {
// Effects: If other is null throws NullPointerException else
// returns the Polynomial this + other
Polynomial larger, smaller;
if (degree > other.degree){
larger = this;
smaller = other;
}
else {
larger = other;
smaller = this;
}
int newDegree = larger.degree;
if (degree == other.degree) {
for(int k = degree; k > 0 ; k--) {
if (this.terms[k] + other.terms[k] != 0) {
break;
}
else {
newDegree --;
}
}
}
Polynomial newPoly = new Polynomial(newDegree);
int i;
for (i=0; i <= smaller.degree && i <= newDegree; i++){
newPoly.terms[i] = smaller.terms[i] + larger.terms[i];
}
for(int j=i; j <= newDegree; j++) {
newPoly.terms[j] = larger.terms[j];
}
return newPoly;
}
public Polynomial multiply(Polynomial other) throws NullPointerException {
// Effects: If other is null throws NullPointerException else
// returns the Polynomial this * other
if ((other.degree == 0 && other.terms[0] == 0) ||
(this.degree==0 && this.terms[0] == 0)) {
return new Polynomial();
}
Polynomial newPoly = new Polynomial(degree + other.degree);
newPoly.terms[degree + other.degree] = 0;
for(int i=0; i<=degree; i++) {
for (int j=0; j<= other.degree; j++) {
newPoly.terms[i+j] = newPoly.terms[i+j] + this.terms[i] * other.terms[j];
}
}
return newPoly;
}
At quick glance, looks like this is a problem
for(int i = 0; i < arrayList.size(); i++)
{
Polynomial polynomial = new Polynomial(arrayList.get(i), arrayList.get(i+1));
polynomialarraylist.add(polynomial);
System.out.println("coef" + arrayList.get(i));
System.out.println("degree" + arrayList.get(i+1));
i++;
}
You're doing i++ twice here.
Also, you posted WAY too much code. No one wants to read that much. You're just lucky that, assuming this is the problem, I happened to glance at that.
Also that will throw an arrayindexoutofboundserror since you're doing .get(i+1)
the constructor is set up the way it is because the get(i) gets you the coefficient and the i+1 gets you the degree from the arraylist parameter since when you call add, without those the arraylist contents would be off
THe constructor is suppose to take an Arraylist and put them inisde of an arraylist of polynomials. using the odds as the coefficient and the evens as the degrees of the polynomials.