What is a good way to implement calculations for extended classes? - java

I have the following classes:
public class Node {
private int x;
private int y;
}
public abstract class Map {
protected Node[][] grid;
public abstract Set<Node> findNeighbours(Node node);
}
public class SquareMap extends Map {
private static final int VERTICAL_COST= 10;
private static final int HORIZONTAL_COST= 10;
private static final int DIAGONAL_COST = 14;
#Override
public Set<Node> findNeighbours(Node node) {
//return the 8 adjacent nodes
}
}
public class HexMap extends Map {
private static final int MOVE_COST = 10;
#Override
public Set<Node> findNeighbours(Node node) {
//return the 6 adjacent nodes
}
}
I would like to create a method like
public int calculateMoveCost(Node current, Node target, <whatever else is needed>) {}
Where I only pass in the nodes, and the logic in either the method, or the nodes, or the map recognizes what kind of map I'm using. My current solution looks like this:
private int calculateMoveCost(Node current, Node target, Map map) {
int cost;
if(isHexMap(map)) {
cost = map.getMoveCost();
} else {
if(isSquareMap(map)) {
if(verticalNeighbours(current, target)) {
cost = map.getVerticalMoveCost();
} else {
cost = map.getHorizontalMoveCost();
}
}
}
return cost;
}
When I look at this code, I think there has to be a better way to implement this. Could you recommend a nice object oriented way of implementing this? I can create any reference in any object, the goal is to have a nice solution. Thanks!

I do think there is a right answer for this, just have an abstract getMoveCost method on Map and implement it in each subclass. Then you can just call map.getMoveCost(from, to).
public abstract class Map {
protected Node[][] grid;
public abstract int getMoveCost(Node current, Node target);
public abstract Set<Node> findNeighbours(Node node);
}
public class SquareMap extends Map {
private static final int VERTICAL_COST= 10;
private static final int HORIZONTAL_COST= 10;
private static final int DIAGONAL_COST = 14;
#Override
public Set<Node> findNeighbours(Node node) {
//return the 8 adjacent nodes
}
#Override
public int getMoveCost(Node current, Node target) {
if(verticalNeighbours(current, target)) {
cost = getVerticalMoveCost();
} else {
cost = getHorizontalMoveCost();
}
}
}

Related

Java: Implementing parallel hierarchy of trees and its nodes

In order to practice data structures I'm implementing my own library of Trees. I've begun with BST and in following I'm about to implement AVL Tree, Red-Black Tree and maybe more. AVL & RBT are BST trees as well, so some class hierarchy is rather obvious. The problem I came into is that all those trees have other types of Nodes - AvlNode has balance factor flag, RgbNode has color flag, BstNode doesn't need any additional info (despite of references to parent, children and value which all Nodes need). So I've a hierarchy of Nodes and a hierarchy of Trees. I could give some flag attribute to BstNode and use it in extending classes but it is surely not a good way to do it.
The problem is how to deal with the fact that for example Bst.findNode() will return BstNode but in Avl I need AvlNode despite the findNode() methods will be the same in both (apart of return type).
I need help with planning the hierarchies or if those parallel hierarchies (as a code smell) are in general a bad idea, I need a workaround because I have no clue how to do it in proper way.
BstTree Class:
public class BstTree<T extends Comparable> implements Iterable
{
private BstNode<T> root;
public void addValue(T value)
{
BstNode node = new BstNode(value);
addNode(node);
}
public void addNode(BstNode<T> node)
{
...
}
public boolean removeNode(T value)
{
...
}
public BstNode findNode(T value)
{
...
}
//other less significant methods
}
BstNode class:
public class BstNode<T extends Comparable>
{
private static int lastId = 0;
private int id;
private T value;
private BstNode parent = null;
private BstNode leftChild = null;
private BstNode rightChild = null;
public BstNode(T value) {
this.id = ++lastId;
this.value = value;
}
public boolean isGreaterThan(BstNode n)
{
//...
}
public boolean hasLeftChild()
{
//...
}
public boolean hasRightChild()
{
//...
}
public boolean hasParent()
{
//...
}
public boolean isLeaf()
{
//...
}
public boolean hasOnlyOneChild()
{
//...
}
public BstNode getOnlyChild(BstNode node)
{
...
}
public boolean isLeftChildren()
{
...
}
public BstNode getConsequentNode()
{
...
}
}
I can guess that the separation of responsibilities above may not be perfect, if it's wrong then I might get some of the methods from Node to Tree class but this thing is not a big problem.
I would do something like this:
public abstract class BstTree<T extends Comparable,N extends BstNode<T,N>> {
private N root;
...
public void addValue(T value)
{
N node = newNode(value);
addNode(node);
}
public abstract N newNode(T value);
public void addNode(N node)
{
// ...
}
}
public class BstNode<T extends Comparable,N extends BstNode<T,N>>
{
private T value;
private N parent = null;
private N leftChild = null;
private N rightChild = null;
public BstNode(T value) {
this.value = value;
}
public N getOnlyChild(N node)
{
// ...
}
...
}
public class AVLTree<T extends Comparable> extends BstTree<T,AVLNode<T>> {
...
#Override
public AVLNode<T> newNode(T value) {
return new AVLNode<>(value);
}
}
public class AVLNode<T extends Comparable> extends BstNode<T,AVLNode<T>> {
...
public AVLNode(T value) {
super(value);
}
#Override
public AVLNode<T> getOnlyChild(AVLNode<T> node) {
return super.getOnlyChild(node);
}
...
}

Use an instance of the standard class vector to implement the queue. How does this implementation compare with array based approach?

Here is my code. I have a weird error that I cant figure out. Any and every help would be greatly appreciated. I am a beginner at this level.
public interface QueueInterface<T>
{
public void enqueue(T newEntry);
public T dequeue();
public T getFront();
public boolean isEmpty();
public void clear();
Now I am putting the code for Vector Class which is implemented by the above code. I need help on this part. I think there is an error in the for loop but I am not sure.
import java.util.Vector;
public class VectorQueue implements QueueInterface
{
private Vector queue;
private int frontIndex;
private int backIndex;
private boolean initialized=false;
private static final int DEFAULT_CAPACITY= 50;
private static final int MAX_CAPACITY= 1000;
public VectorQueue()
{
queue=new Vector<>();
frontIndex=backIndex=0;
}
public void enqueue(T newEntry)
{
backIndex++;
queue.add(backIndex, newEntry);
if(frontIndex==0)
frontIndex++;
}
public T dequeue()
{
if(frontIndex!=0)
{
T rEntry=queue.elementAt(frontIndex);
for (int i =frontIndex;i++)
queue.add(frontIndex, queue.elementAt(frontIndex+1));
queue.remove(backIndex);
backIndex--;
if(backIndex==0)
frontIndex=0;
return rEntry;
}
return null;
}
public T getFront()
{
if(frontIndex!=0)
return queue.elementAt(frontIndex);
return null;
}
public boolean isEmpty()
{
if(backIndex==0)
return true;
return false;
}
public void clear()
{
int index=backIndex;
for(int i=frontIndex;i<=backIndex;i++)
queue.removeElementAt(index--);
frontIndex=backIndex=0;
}
}

Having a static nested class be a subtype of the enclosing class when trying to implement a Tree data type

I have been following along in the book Data Structures (Into Java) by Paul Hilfinger and I am having trouble implementing some part of a Tree structure.
When during the implementation, the book suggested that we have a nested static class represent an empty tree to make so methods using a Tree do not have to check for null pointers. The example code looks like this
public class Tree<T> {
public Tree(T label) ...
public Tree(T label, int k) ...
public T label() ...
public int degree() ...
public int numChildren() ...
public Tree<T> child(int k) ...
public void setChild(int k, Tree<T> C) ...
public boolean isEmpty() { return false }
public final Tree<T> EMPTY = new EmptyTree();
static class EmptyTree<T> extends Tree<T> {
private EmptyTree() {}
public boolean isEmpty() { return true }
public int degree() { return 0 }
public int numChildren() { return 0 }
public Tree<T> getChild(int i) {
throw new Exception;
}
public T label() {
throw new Exception;
}
}
}
Here is my implementation:
public class NonEmptyGTree<T> {
public NonEmptyGTree(T label, int arity) {
this.label = label;
children = (NonEmptyGTree<T>[]) new Object[arity];
for (int i = 0; i < arity; i++)
children[i] = EMPTY;
}
public NonEmptyGTree() {
}
public NonEmptyGTree<T> getChild(int i) {
return children[i];
}
public void setChild(int i, NonEmptyGTree<T> set) {
if (children[i].isEmpty()) deg += 1;
children[i] = set;
}
public T getLabel() {
return label;
}
public void setLabel(T label) {
this.label = label;
}
public int numChildren() {
return children.length;
}
public int degree() {
return deg;
}
public boolean isLeaf() {
return deg == 0;
}
public boolean isEmpty() {
return false;
}
public class EmptyGTree<T> extends NonEmptyGTree<T> {
private EmptyGTree() {}
public int degree() { return 0; }
public int numChildren() {
return 0;
}
public NonEmptyGTree<T> getChild(int i) {
throw new IllegalStateException();
}
public void setChild(int i, NonEmptyGTree<T> set) {
throw new IllegalStateException();
}
public T getLabel() {
throw new IllegalStateException();
}
public void setLabel(T label) {
throw new IllegalStateException();
}
public boolean isEmpty() {
return true;
}
}
private T label;
private NonEmptyGTree[] children;
private int deg = 0;
public final NonEmptyGTree<T> EMPTY = new EmptyGTree<T>();
}
This made sense to me since that way we won't have to check for null pointers when we use trees elsewhere, but when I try to initialize a tree, it goes into a loop with the Tree initializing EMPTY then EMPTY calling super() which then initializes Tree again looping.
I then tried to use a Null design pattern where I made a Tree interface and and then had two files implementing it, one for an empty tree and a nonempty tree. This seems messy to me because then for any subtype of a Tree, I would have to split it up into a nonempty tree and empty tree for every subtype. It seems like the idea of making an empty tree should stop with just this one implementation since functionally all empty trees are the same (if you do not need to access the parent nodes).
Is it not possible to make it so that I would only have to implement the EmptyTree once? Or is what I am asking to do not possible?

Trouble casting an interface to an implemented class

Here is my class:
public class LinkedListSet implements Set {
private class Node //much easier as a private class; don't have to extend
{
private int data;
private Node next;
public Node (){}
public Node (int x)
{
data = x;
}
public int data()
{
return data;
}
public Node next()
{
return next;
}
}
private Node first;
private int Size;
private int whichList; //used to identify the particular LL object
Here is my interface:
public interface Set {
public boolean isEmpty();
public void makeEmpty();
public boolean isMember(int x);
public void add(int x);
public void remove(int y);
public void union(Set other, Set result);
public void intersection (Set other, Set result);
public void difference (Set other, Set result);
#Override
public String toString();
#Override
public boolean equals(Object other);
public void setList(int i); //i added this to use it as an identifier for each
//list element in the set array
public String getListId(); //these two extra methods make life easier
}
I have a method like this (in the LinkedListSet class):
public void difference (Set other, Set result)
{
if (other.isEmpty())
{
System.out.println("The set is empty before cast");
}
LinkedListSet othr = (LinkedListSet) other;
LinkedListSet res = (LinkedListSet) result;
if (this.isEmpty() || othr.isEmpty())
{
if (othr.isEmpty())
System.out.println("The set is empty after cast");
if (this.isEmpty())
System.out.println("This is also empty");
return;
}
differenceHelper(this.first, othr.first, res);
result = res;
}// the print statements were added for debugging
The problem is, in the above method I am unable to cast the Set Other into its linked list implementation. When I call this method in the main program, the parameter is actually of type linked list (so I don't get any errors obviously).
However, all the instance variables are null. The list is empty before and after I cast it (when it actually isn't empty). I know this is because the interface doesn't include any information about the Nodes, but is there anything I can do other than editing the interface to incorporate the Node?
I hope I've made this clear enough. Any help would be appreciated.
edit:
In the main program I created an array of Sets.
Set[] sets = new Set[7];
for (int i = 0; i< sets.length; i++) //initialize each element
{
sets[i] = new LinkedListSet();
}
each list has nodes with data values which are added on later on in the code...
then I call the difference method.
sets[0].difference(sets[1], sets[4])
sets[1].isEmpty returns true for some reason (even though it is not).
If I were to do something like:
System.out.println(sets[1].first.data()) I would have no problem whatsoever.
For some reason all the values become null when the parameters are passed to the difference method.
public boolean isEmpty()
{
return first == null;
}
I tested what you are trying to do with the following code and I see no problems:
import org.junit.Test;
public class RandomCastTest {
public interface Set {
boolean isEmpty();
void add(int x);
void difference(Set other, Set result);
#Override
String toString();
#Override
boolean equals(Object other);
}
public class LinkedListSet implements Set {
private class Node //much easier as a private class; don't have to extend
{
private int data;
private Node next;
public Node() {
}
public Node(int x) {
data = x;
}
public int data() {
return data;
}
public Node next() {
return next;
}
public void next(Node node) {
next = node;
}
}
private Node first;
private int Size;
private int whichList; //used to identify the particular LL object
#Override
public boolean isEmpty() {
return first == null;
}
#Override
public void add(int x) {
Node node = new Node(x);
if (first == null) {
first = node;
} else {
Node currentNode;
Node nextNode = first;
do {
currentNode = nextNode;
nextNode = currentNode.next();
} while (nextNode != null);
currentNode.next(node);
}
Size++;
}
#Override
public void difference(Set other, Set result) {
if (other.isEmpty()) {
System.out.println("The set is empty before cast");
}
LinkedListSet othr = (LinkedListSet) other;
LinkedListSet res = (LinkedListSet) result;
if (this.isEmpty() || othr.isEmpty()) {
if (othr.isEmpty())
System.out.println("The set is empty after cast");
if (this.isEmpty())
System.out.println("This is also empty");
return;
}
result = res;
}
}
#Test
public void test() {
Set[] sets = new Set[7];
for (int i = 0; i < sets.length; i++) {
sets[i] = new LinkedListSet();
}
for (int i = 0; i < 5; i++) {
sets[1].add(i);
}
for (int i = 5; i < 10; i++) {
sets[0].add(i);
}
sets[0].difference(sets[1], sets[4]);
// ... find difference
}
}
To simplify I removed unimplemented methods from the interface. Also added the add method implementation. Please see if it works for you.

DRY maxima tracking

Suppose I am importing table entries, where a single entry can be stored in a class:
class Foo {
int i1;
int i2;
double d1;
}
After the import is complete, I will need to have access to the imported values themselves, as well as to their normalized versions. So far, I have implemented this functionality as follows:
class FooWithMaxTracking {
private int i1;
private static int i1_max=0;
public void setI1(int value){
this.i1 = value;
if (value > i1_max) { i1_max = value; }}
public int getI1(){
return i1;}
public double normI1(){
return i1/((double)i1_max);}
private int i2;
private static int i2_max=0;
public void setI2(int value){ <code identical to written above> }
public int getI2(){ ... }
public double normI2(){ ... }
// and another set of similar 2 variables & 3 functions for 'double d1'
}
In this implementation I strongly dislike the fact that I had to write the same code many times (only three in this example, but about ten times in the real project). Is there any way to make the code more DRY ("don't repeat yourself")?
If you do not mind a slight loss of performance, you can put all the maxima in a static Map, define a class that holds a getter, a setter, and a norm methods, and replace the individual variables with instances of that class:
private static Map<String,Object> max = new HashMap<String,Object>();
private static class IntMaxTrack {
private final String key;
private int value;
public IntMaxTrack(String k, int v) {
key = k;
value = v;
max.put(key, value);
}
public int get() { return value; }
public void set(int v) {
int m = ((Integer)max.get(key)).intValue();
value = v;
if (value > m) {
max.put(key, value);
}
}
public double norm() {
int m = ((Integer)max.get(key)).intValue();
return val / ((double)m);
}
}
Make a similar class for double, i.e. DblMaxTrack Now you can replace primitives with instances of these classes, and call their get, set, and norm from the corresponding methods of your class.
What about defining one class with the necessary code, like:
public class Bar {
private int i1;
private static int i1_max = 0;
public void setI1(int value) {
// ...
}
public int getI1() {
// ...
}
public double normI1() {
// ...
}
}
And using it sevearl times, like:
class FooWithMaxTracking {
one = new Bar();
two = new Bar();
three = new BarForDouble();
}

Categories

Resources