I am having a problem when i assign objects, the object produces a reference duplicate that changes the value in original object.
This is my original object
Node root = new Node();
root.filingState("input.txt");
After pushing my root in deque data structure, i retrieve it in a tmp variable
Node tmp = deque.pop();
After that, i want my tmp variable to apply all the operators(up, down, left, right, which ever ones are possible) and check for the best result.
if ( !tmp.goalTest(goal) ) {
if ( tmp.ifDown() ) {
if ( !visited[tmp.getX()+1][tmp.getY()] ) {
newDown = new Node(tmp);
newDown.moveDown();
} else newDown = null;
} // #EndOfDown!
if ( tmp.ifUp() ) {
if ( !visited[tmp.getX()-1][tmp.getY()] ) {
newUp = new Node(tmp);
newUp.moveUp();
} else newUp = null;
} // #EndOfUp!
if ( tmp.ifLeft() ) {
if ( !visited[tmp.getX()][tmp.getY()-1] ) {
newLeft = new Node(tmp);
newLeft.moveLeft();
} else newLeft = null;
} // #EndOfMoveLeft!
if ( tmp.ifRight() ) {
if ( !visited[tmp.getX()][tmp.getY()+1] ) {
newRight = new Node(tmp);
newRight.moveRight();
} else newRight = null;
} // #EndOfMoveRight!
} else break;
Operator functions
public boolean ifUp ( ) { return y_blank-1 >= 0; }
public boolean ifDown ( ) { return y_blank+1 <= 4; }
public boolean ifLeft ( ) { return x_blank-1 >= 0; }
public boolean ifRight ( ) { return x_blank+1 <= 4; }
/* Movement functions
Allows a user to move his blank on board
*/
public void moveUp ( ) {
board[y_blank][x_blank] = board[y_blank-1][x_blank];
board[y_blank-1][x_blank] = 'B';
y_blank -= 1;
} // #EndOfMoveUp!
public void moveLeft ( ) {
board[y_blank][x_blank] = board[y_blank][x_blank-1];
board[y_blank][x_blank-1] = 'B';
x_blank -= 1;
} // #EndOfMoveLeft!
public void moveRight ( ) {
board[y_blank][x_blank] = board[y_blank][x_blank+1];
board[y_blank][x_blank+1] = 'B';
x_blank += 1;
} // #EndOfMoveRight!
public void moveDown ( ) {
board[y_blank][x_blank] = board[y_blank+1][x_blank];
board[y_blank+1][x_blank] = 'B';
y_blank += 1;
} // #EndOfMoveDown!
newDown fails of 1st iteration since it doesn't fulfill the condition by my other Nodes pass the condition.
after my 1st newUp applies its operator, it changes the tmp Node aswell. Allowing newLeft, newRight to apply operators to the newly tmp Node values.
class Node.java
private char[][] board;
private int x_blank = -1;
private int y_blank = -1;
private Node parent = null;
private Node up = null;
private Node left = null;
private Node right = null;
private Node down = null;
/* Constructor
Allocates board to a 5x5 2D Array
*/
public Node ( ) { board = new char[5][5]; }
i tried creating a copy constructor but doesn't solve the problem.
Copy constructor
public Node ( Node tmp ) {
this.board = new char[5][5];
for ( int i=0; i<5; ++i ) {
for ( int j=0; j<5; ++j ) this.board[i][j] = tmp.board[i][j];
}
this.x_blank = tmp.x_blank;
this.y_blank = tmp.y_blank;
if ( tmp.parent != null ) this.parent = tmp.parent;
if ( tmp.up != null ) this.up = tmp.up;
if ( tmp.left != null ) this.left = tmp.left;
if ( tmp.right != null ) this.right = tmp.right;
if ( tmp.down != null ) this.down = tmp.down;
}
so my question is that, how can i create an Object that can hold the values of some other Object, but when i apply the operator on the newly created object, it doesn't change the value of the original Object.
Your copy constructor won't automatically be used on assignment of an instance of that object to a new variable. It is intended in Java that object assignments are by reference. You need to explicitly use your copy constructor in the assignment:
Node tmp = new Node(deque.pop());
I think the best way is to implement a clone function that will create a new object with the same value, then you will not change the value of the original Object.
for example:
clone(Node mynode){
return new Node(mynode.getValue());
}
Related
I have been trying to construct a linked list where there are 3 different ways to view the code, either the current double value or the previous or next node. The problem I seem to be running into is that in essecense I have been creating a new linked list whenever storing the next or previous node of the current node rather than linking it.
This creates 2 problems:
It takes up a ridicolous amount of space
It creates makes bugs and errors common and hard to spot
I want to know if there is a better way to construct linked lists than this method or if I am running into these 2 problems for reasons different than I believe. My code is down below if you want to see what I have been trying to do.
package algs662;
import java.util.*;
//This whole file is about assembling and sorting data
public class BigSort
{
//The Node is an element that represents the current position
//of a linked list and what is immediately to its left or right static class Node
{
//this represents the Node itself
public Node() { }
//this represents its current element
public double item;
//this represents the node to its right
public Node next;
//this represents the node to its left
public Node prev;
}
//this represents the size of the Linked List
int N;
//this is the main node
Node first;
//this is a variable that will be false when the function
//using this hasn't ran once and will be true when it has
public boolean once = false;
//This will create an empty node where new elements can be added
public BigSort()
{
first = null;
N = 0;
checkInvariants ();
}
//This represents the max value
static double max;
private void myassert( String s, boolean b )
{
if( !b ) throw new AssertionError( "Assertion failed: " + s );
}
private void checkInvariants()
{
myassert( "Empty <==> first==null", (N == 0) == (first == null) );
Node x = first;
for( int i = 0; i < N; ++i )
{
if( x==null )
{
throw new Error( "List too short!" );
}
x = x.next;
}
myassert("EndOfList == null", x == null);
}
private Node reset( Node n )
{
Node saved;
while( n.prev != null )
{
saved = n;
n = n.prev;
}
return n;
}
//This function will delete a specific number from a list
private void delete( double num )
{
if( once == false )
{
Node curr = first;
if( N == 0 ) { throw new Error( "There is no list" ); }
else if( N == 1 )
{
if( curr.item == num )
{
first = null;
return;
}
else
{
throw new Error( "Number inputted doesn't exist" );
}
}
else if( curr != null )
{
if( curr.item == num )
{
first = curr.next;
--N;
return;
}
while( curr.next != null )
{
if( curr.next.item != num )
{
curr.prev = curr;
curr = curr.next;
}
else if( curr.next.item == num )
{
curr.next = curr.next.next;
--N;
reset( curr );
return;
}
}
if( curr.item == num )
{
first = curr.prev;
curr.next = null;
--N;
reset( curr );
return;
}
else if( curr.next == null )
{
throw new Error( "Number inputted doesn't exist" );
}
}
}
else
{
return;
}
}
private void push( double i )
{
Node temp = new Node();
temp.item = i;
Node saved;
Node curr = first;
if( this.first == null )
{
first = temp;
return;
}
else
{
while( curr.next != null )
{
saved = curr;
curr = curr.next;
curr.prev = saved;
}
saved = curr;
curr.next = temp;
curr = curr.next;
curr.prev = saved;
}
this.N++;
first = reset( curr );
}
private void pushFront( double i )
{
Node temp = new Node();
Node saved;
temp.item = i;
temp.next = first;
saved = temp;
temp = temp.next;
temp.prev = saved;
temp = temp.prev;
++N;
first = temp;
}
private void pushPos( int pos, double i )
{
Node temp = new Node();
Node store = new Node();
Node last = new Node();
store.item = i;
temp = first;
Node saved;
double pastval;
double savedval;
if( pos > N || pos < 0 )
{
throw new Error( "The position inputted doesn't exist" );
}
else
{
if( pos == 0 )
{
store.item = i;
store.next = first;
++N;
first = store;
return;
}
for( int x = 0; x < pos; ++x )
{
saved = temp;
temp = temp.next;
temp.prev = saved;
}
pastval = temp.item;
temp.item = i;
temp = temp.next;
savedval = temp.item;
temp.item = pastval;
while( temp.next != null )
{
// Does nothing??
}
first=reset( temp );
return;
}
}
private double pop()
{
Node popped;
Node temp = first;
while( temp.next.next !=null )
{
temp = temp.next;
}
popped = temp.next;
temp.next = null;
--N;
System.out.print( popped );
first = temp;
return popped.item;
}
private void incurSort()
{
double swap = 0;
int u = 0;
for( int y = 1; y < N - 1; ++y )
{
//this compares the current item to the next item
if( first.item > first.next.item )
{
u = y;
while( u > 0 && first.prev != null )
{
if( first.item > first.next.item )
{
swap = first.item;
first.item = first.next.item;
first.next.item = swap;
}
first = first.prev;
--u;
}
}
while( u < y && first.next != null )
{
first = first.next;
++u;
}
}
reset(first);
}
public static void main( String args[] )
{
double swap = 0;
BigSort b = new BigSort();
int u = 0;
// Adding elements in the list
// using add() method
b.push( 1.0 );
b.push( 3.0 );
b.push( 5.0 );
b.push( 2.0 );
b.push( 20.0 );
b.push( 11.0 );
b.push( 13.0 );
b.push( 17.0 );
Node two = b.first;
b.incurSort();
b.delete( 11.0 );
b.delete( 1.0);
b.delete( 20.0);
b.delete( 5.0);
b.delete( 3.0);
b.delete( 13.0);
b.pushFront( 10.0);
b.pushFront( 2.0 );
b.pushFront( 16.0 );
b.pushFront( 50.0 );
b.pushFront( 100.0 );
b.pushPos( 2, 20.0 );
System.out.println( b.pop() );
System.out.println( b.pop() );
System.out.println( b.pop() );
System.out.println( b.pop() );
System.out.println( b.pop() );
System.out.println( b.pop() );
System.out.println( "stuff left over" );
for( int k = 0; k <= b.N - 1; ++k )
{
if( b.first != null )
{
System.out.println( b.first.item );
b.first = b.first.prev;
}
else
{
System.out.println( "it broke at " + k );
break;
}
}
}
}
I have a nearly fully functional program but I am not able to format the output correctly. I am in desperate need of help as my project is past due already.
I am a student working on a program that reads in a simple text file and creates a graph object of nodes from the input file. I am then, supposed to use a heap class to build the nodes into a Min-heap. Finally I am supposed to call a heap sort method to sort the nodes (preferably in descending order)
I believe that my methods are correct and that my data is being correctly built into a min heap and is being correctly sorted. The only problem I am having is formatting the output which should be simple but for some reason isn't. The idea is this:
my graph object contains 2 arrayLists the first is the unordered node list that was created from the input text file. The second is a blank arrayList that I am trying to copy nodes one at a time.
I am trying to use a for loop or a while loop to first copy one single node into the empty ArrayList then call my build heap method to build a Min heap of only 1 element, then call my sort method to sort the heap of 1 element. Then, I want to copy in a second node and again build a min heap of 2 elements and then call my sort method on the 2 element heap. Then, copy in a third node and build the heap with 3 nodes, and then call the sort on the 3 element heap, and so on and so forth until all elements have been copied into the array list and the full heap is built and the sort method is called on all elements.
My 3 element test file looks like this:
~ val X Y Z
Xerxes 0 ~ ~ ~
York -1 ~ ~ ~
Zardoz 1 ~ ~ ~
My 6 element test file looks like this:
~ val A B C D E F
Alfa 4 ~ ~ ~ ~ ~ ~
Bravo 6 ~ ~ ~ ~ ~ ~
Charlie -3 ~ ~ ~ ~ ~ ~
Delta -6 ~ ~ ~ ~ ~ ~
Echo 0 ~ ~ ~ ~ ~ ~
Foxtrot 55 ~ ~ ~ ~ ~ ~
the output should look something like this:
Heaps:
X
YX
YXZ
HeapSort:
YXZ
XZY
ZXY
I am using several "test" files including one with 3 elements and one with 6 elements.
My classes are as follows:
import java.io.*;
public class DelivB {
File inputFile;
File outputFile;
PrintWriter output;
Graph g;
public DelivB( File in, Graph gr ) {
inputFile = in;
g = gr;
// Get output file name.
String inputFileName = inputFile.toString();
String baseFileName = inputFileName.substring( 0, inputFileName.length()-4 ); // Strip off ".txt"
String outputFileName = baseFileName.concat( "_out.txt" );
outputFile = new File( outputFileName );
if ( outputFile.exists() ) { // For retests
outputFile.delete();
}
try {
output = new PrintWriter(outputFile);
writeGraphInfo(output);
//System.out.println("=============================\n" + "testing testing testing Deliv B Class");
}
catch (Exception x ) {
System.err.format("Exception: %s%n", x);
System.exit(0);
}
//System.out.println( "DelivB: To be implemented");
//System.out.println("\nDeliv B Class ++++++++++++++++++++++++++++++++++");
}
public Graph getG() {
return g;
}
public void setG(Graph g) {
this.g = g;
}
/** Read the file containing the Strings, line by line, then process each line as it is read.
**/
public void writeGraphInfo( PrintWriter output ) {
try {
// output the graph information.
// I chose to output it to the console as well as the file for debugging purposes.
System.out.println( "\n\n=========================================================================\n\n");
System.out.println( g );
output.println( g );
}
catch (Exception x ) {
System.err.format("ExceptionInner: %s%n", x);
System.exit(0);
}
output.close();
}
}
// NEXT CLASS
//===================================================
import java.util.*;
// A node of a graph for the Spring 2018 ICS 340 program
public class Node {
String name;
String val; // The value of the Node
String abbrev; // The abbreviation for the Node
ArrayList<Edge> outgoingEdges;
ArrayList<Edge> incomingEdges;
public Node( String theAbbrev ) {
setAbbrev( theAbbrev );
val = null;
name = null;
outgoingEdges = new ArrayList<Edge>();
incomingEdges = new ArrayList<Edge>();
}
public String getAbbrev() {
return abbrev;
}
public String getName() {
return name;
}
public String getVal() {
return val;
}
public ArrayList<Edge> getOutgoingEdges() {
return outgoingEdges;
}
public ArrayList<Edge> getIncomingEdges() {
return incomingEdges;
}
public void setAbbrev( String theAbbrev ) {
abbrev = theAbbrev;
}
public void setName( String theName ) {
name = theName;
}
public void setVal( String theVal ) {
val = theVal;
}
public void addOutgoingEdge( Edge e ) {
outgoingEdges.add( e );
}
public void addIncomingEdge( Edge e ) {
incomingEdges.add( e );
}
}
//NEXT CLASS ==================================================
//import java.util.*;
// Edge between two nodes
public class Edge {
String label;
Node tail;
Node head;
public Edge( Node tailNode, Node headNode, String theLabel ) {
setLabel( theLabel );
setTail( tailNode );
setHead( headNode );
}
public String getLabel() {
return label;
}
public Node getTail() {
return tail;
}
public Node getHead() {
return head;
}
public void setLabel( String s ) {
label = s;
}
public void setTail( Node n ) {
tail = n;
}
public void setHead( Node n ) {
head = n;
}
}
//NEXT CLASS ===================================================
import java.util.*;
public class Heap
{
int heapSize;
Graph gr;
ArrayList<Node> unordered_nodelist;
ArrayList<Node> ordered_nodelist;
Node dummy = new Node("dummy node");
//constructor for heap object with the following attributes:
//a graph object and an int representing the size of an arraylist of nodes
public Heap(Graph g)
{
unordered_nodelist = g.getNodeList();
heapSize = unordered_nodelist.size();
ordered_nodelist = new ArrayList<Node>();
//for (int i = 0; i < heapSize; i++)
//ordered_nodelist.add(dummy);
//probably don't need this graph variable
gr = g;
}
//getters and setters
public ArrayList<Node> getUnordered_nodelist() {
return unordered_nodelist;
}
public void setUnordered_nodelist(ArrayList<Node> unordered_nodelist) {
this.unordered_nodelist = unordered_nodelist;
}
public ArrayList<Node> getOrdered_nodelist() {
return ordered_nodelist;
}
public void setOrdered_nodelist(ArrayList<Node> ordered_nodelist) {
this.ordered_nodelist = ordered_nodelist;
}
public int getHeapSize() {
return heapSize;
}
public void setHeapSize(int heapSize) {
this.heapSize = heapSize;
}
//heap methods
public int Parent(ArrayList<Node> A, int i)
{
//if (i == 1)
//return (Integer)null;
if (i%2 != 0)
return i/2;
else
return (i-1)/2;
}
public int Left(ArrayList<Node> A, int i)
{
//while (A.get(i).getVal() != null && A.get(i).getName() != null)
//{
//if (2*i < heapSize)
return (2*i)+1;
//else
//return (Integer)null;
//}
}
public int Right(ArrayList<Node> A, int i)
{
//if ((2*i)+1 < heapSize)
return 2*i+2;
//else
//return (Integer)null;
}
public void Heapify(ArrayList<Node> A, int i)
{
Node smallest;
Node temp;
int index;
int l = Left(A,i);
int r = Right(A,i);
while (A.get(i).getVal() != null && A.get(i).getName() != null)
{
if (l <= heapSize-1 && Integer.parseInt(A.get(l).getVal()) < Integer.parseInt(A.get(i).getVal()))
{
//left child is smaller
smallest = A.get(l);
index = l;
}
else
{
//parent node is smaller
smallest = A.get(i);
index = i;
}
if (r <= heapSize-1 && Integer.parseInt(A.get(r).getVal()) < Integer.parseInt(smallest.getVal()))
{
//right child is smaller
smallest = A.get(r);
index = r;
}
if (index != i)
{
//if the smallest element is not the parent node
//swap the smallest child with the parent
temp = A.get(i);
A.set(i, A.get(index));
A.set(index, temp);
//recursively call heapify method to check next parent/child relationship
Heapify(A, index);
}
}
}
//method to construct min heap from unordered arraylist of nodes
public void Build_min_Heap(ArrayList<Node> A)
{
for (int k = 0; k<A.size()-1; k++)
{
//while (A.get(k).getVal() != null && A.get(k).getName() != null)
//{
int i;
int heapSize = A.size();
for (i = (heapSize/2); i>=0; i--)
{
Heapify(A, i);
System.out.print(gr.toString2()+"\n");
}
//}
}
}
//decreases the value of a given node, used with insert method
public void heap_Decrease_Key(ArrayList<Node> A, int i, int key)
{
Node parent;
Node child;
Node temp;
if (key > i)
{
System.out.println("error key must be less than i");
//break;
}
A.get(i).setVal(Integer.toString(key));
while(i>0 && Integer.parseInt(A.get(Parent(A,i)).getVal()) > Integer.parseInt(A.get(i).getVal()) )
{
parent = A.get(Parent(A,i));
child = A.get(i);
temp = parent;
//take the child node and place it in the parent node's place
A.set(Parent(A,i), child);
//take the parent node and place it in the child node's place
A.set(i, temp);
}
}
//method to sort in descending order, a min heap
public void heap_Sort(ArrayList<Node> A)
{
Node temp;
for (int k = 0; k<A.size()-1; k++)
{
//while (A.get(k).getVal() != null && A.get(k).getName() != null)
//{
Build_min_Heap(A);
System.out.println(gr.toString2()+"\n");
for(int i = A.size()-1; i >= 1; i--)
{
//exchange a[1] with a[i]
temp = A.get(0);
A.set(0, A.get(i));
A.set(i, temp);
//decrement heapSize
heapSize--;
//recursive heapify call
Heapify(A, 0);
}
//}
}
}
public Node heap_Extract(ArrayList<Node> A)
{
Node min;
min = A.get(0);
A.set(0, A.get(heapSize-1));
//decrement heapSize
heapSize--;
Heapify(A, 0);
return min;
}
public void heap_Insert(ArrayList<Node> A, int key)
{
heapSize++;
A.get(heapSize-1).setVal(Integer.toString(2147483647));
heap_Decrease_Key(A, heapSize-1, key);
}
public String toString()
{
String s = "Graph g.\n";
//s += "Heaps: \n";
if ( ordered_nodelist.size() > 0 )
{
//for loop to traverse an ArrayList of Nodes
for(Node n : ordered_nodelist)
{
//output string to print each node's character abbreviation
String t = n.getAbbrev();
s = s.concat(t);
}
}
return s;
}
}
//NEXT CLASS =================================================
import java.util.*;
public class Heap
{
int heapSize;
Graph gr;
ArrayList<Node> unordered_nodelist;
ArrayList<Node> ordered_nodelist;
Node dummy = new Node("dummy node");
//constructor for heap object with the following attributes:
//a graph object and an int representing the size of an arraylist of nodes
public Heap(Graph g)
{
unordered_nodelist = g.getNodeList();
heapSize = unordered_nodelist.size();
ordered_nodelist = new ArrayList<Node>();
//for (int i = 0; i < heapSize; i++)
//ordered_nodelist.add(dummy);
//probably don't need this graph variable
gr = g;
}
//getters and setters
public ArrayList<Node> getUnordered_nodelist() {
return unordered_nodelist;
}
public void setUnordered_nodelist(ArrayList<Node> unordered_nodelist) {
this.unordered_nodelist = unordered_nodelist;
}
public ArrayList<Node> getOrdered_nodelist() {
return ordered_nodelist;
}
public void setOrdered_nodelist(ArrayList<Node> ordered_nodelist) {
this.ordered_nodelist = ordered_nodelist;
}
public int getHeapSize() {
return heapSize;
}
public void setHeapSize(int heapSize) {
this.heapSize = heapSize;
}
//heap methods
public int Parent(ArrayList<Node> A, int i)
{
//if (i == 1)
//return (Integer)null;
if (i%2 != 0)
return i/2;
else
return (i-1)/2;
}
public int Left(ArrayList<Node> A, int i)
{
//while (A.get(i).getVal() != null && A.get(i).getName() != null)
//{
//if (2*i < heapSize)
return (2*i)+1;
//else
//return (Integer)null;
//}
}
public int Right(ArrayList<Node> A, int i)
{
//if ((2*i)+1 < heapSize)
return 2*i+2;
//else
//return (Integer)null;
}
public void Heapify(ArrayList<Node> A, int i)
{
Node smallest;
Node temp;
int index;
int l = Left(A,i);
int r = Right(A,i);
while (A.get(i).getVal() != null && A.get(i).getName() != null)
{
if (l <= heapSize-1 && Integer.parseInt(A.get(l).getVal()) < Integer.parseInt(A.get(i).getVal()))
{
//left child is smaller
smallest = A.get(l);
index = l;
}
else
{
//parent node is smaller
smallest = A.get(i);
index = i;
}
if (r <= heapSize-1 && Integer.parseInt(A.get(r).getVal()) < Integer.parseInt(smallest.getVal()))
{
//right child is smaller
smallest = A.get(r);
index = r;
}
if (index != i)
{
//if the smallest element is not the parent node
//swap the smallest child with the parent
temp = A.get(i);
A.set(i, A.get(index));
A.set(index, temp);
//recursively call heapify method to check next parent/child relationship
Heapify(A, index);
}
}
}
//method to construct min heap from unordered arraylist of nodes
public void Build_min_Heap(ArrayList<Node> A)
{
for (int k = 0; k<A.size()-1; k++)
{
//while (A.get(k).getVal() != null && A.get(k).getName() != null)
//{
int i;
int heapSize = A.size();
for (i = (heapSize/2); i>=0; i--)
{
Heapify(A, i);
System.out.print(gr.toString2()+"\n");
}
//}
}
}
//decreases the value of a given node, used with insert method
public void heap_Decrease_Key(ArrayList<Node> A, int i, int key)
{
Node parent;
Node child;
Node temp;
if (key > i)
{
System.out.println("error key must be less than i");
//break;
}
A.get(i).setVal(Integer.toString(key));
while(i>0 && Integer.parseInt(A.get(Parent(A,i)).getVal()) > Integer.parseInt(A.get(i).getVal()) )
{
parent = A.get(Parent(A,i));
child = A.get(i);
temp = parent;
//take the child node and place it in the parent node's place
A.set(Parent(A,i), child);
//take the parent node and place it in the child node's place
A.set(i, temp);
}
}
//method to sort in descending order, a min heap
public void heap_Sort(ArrayList<Node> A)
{
Node temp;
for (int k = 0; k<A.size()-1; k++)
{
//while (A.get(k).getVal() != null && A.get(k).getName() != null)
//{
Build_min_Heap(A);
System.out.println(gr.toString2()+"\n");
for(int i = A.size()-1; i >= 1; i--)
{
//exchange a[1] with a[i]
temp = A.get(0);
A.set(0, A.get(i));
A.set(i, temp);
//decrement heapSize
heapSize--;
//recursive heapify call
Heapify(A, 0);
}
//}
}
}
public Node heap_Extract(ArrayList<Node> A)
{
Node min;
min = A.get(0);
A.set(0, A.get(heapSize-1));
//decrement heapSize
heapSize--;
Heapify(A, 0);
return min;
}
public void heap_Insert(ArrayList<Node> A, int key)
{
heapSize++;
A.get(heapSize-1).setVal(Integer.toString(2147483647));
heap_Decrease_Key(A, heapSize-1, key);
}
public String toString()
{
String s = "Graph g.\n";
//s += "Heaps: \n";
if ( ordered_nodelist.size() > 0 )
{
//for loop to traverse an ArrayList of Nodes
for(Node n : ordered_nodelist)
{
//output string to print each node's character abbreviation
String t = n.getAbbrev();
s = s.concat(t);
}
}
return s;
}
}
//NEXT CLASS ===============================================
import java.util.*;
public class Graph {
ArrayList<Node> nodeList;
ArrayList<Edge> edgeList;
public Graph() {
nodeList = new ArrayList<Node>();
edgeList = new ArrayList<Edge>();
}
public ArrayList<Node> getNodeList() {
return nodeList;
}
public ArrayList<Edge> getEdgeList() {
return edgeList;
}
public void addNode( Node n ) {
nodeList.add( n );
}
public void addEdge( Edge e ) {
edgeList.add( e );
}
//overridden toString() method to output both Nodes and the edges incumbent upon them
public String toString() {
String s = "Graph g.\n";
if ( nodeList.size() > 0 ) {
//for loop to traverse an ArrayList of Nodes
for( Node n : nodeList ) {
//output string to print basic labels for each node
String t = "\nNode " + n.getName() + ", abbrev " + n.getAbbrev() + ", value " + n.getVal() + "\n";
s = s.concat(t);
//for loop to traverse an ArrayList of outgoing Edges incumbent upon
//the given node in each iteration of the outer for loop
for(Edge a : n.getOutgoingEdges()){
//output String to print data about each outgoing edge
String q = n.getName() + " has edge to: " + a.getHead().getName() + " labeled: " + a.getLabel() + "\n";
s = s.concat(q);
}
//for loop to traverse an ArrayList of incomming Edges incumbent upon
//the given node in each iteration of the outer for loop
for(Edge a : n.getIncomingEdges()){
//output string to print data about each incomming edge
String r = n.getName() + " has edge from: " + a.getTail().getName() + " labeled: " + a.getLabel() + "\n";
s = s.concat(r);
}
}
s = s.concat("\n");
}
return s;
}
public String toString2()
{
String s = "Graph g.\n";
if ( nodeList.size() > 0 )
{
//for loop to traverse an ArrayList of Nodes
for( Node n : nodeList )
{
//output string to print each node's mnemonic
String t = n.getAbbrev();
s = s.concat(t);
}
}
return s;
}
}
//NEXT CLASS ==============================================
import javax.swing.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
/** ProgramA simply reads a file containing rows of space-separated Strings,
** your assignment is to print out those strings interpreted as a graph.
**
** #author
** Mike Stein
**/
public class Prog340 extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L; // Keep Eclipse happy.
File inputFile;
File outputFile;
PrintWriter output;
JFileChooser fileChooser;
Graph g;
Heap h;
String[] comboBoxList; // For putting names in Combo Box
/** The main method instantiates a Prog340 class, which includes giving you a choice of things to do.
** The only one active now will be reading the graph file and having you parse it.
**
** #param args
** - Not used
**
** #throws FileNotFoundException
** - Thrown if the file selected is not found. Shouldn't happen with a FileChooser.
**/
public static void main(String[] args) throws FileNotFoundException {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
/** Create and show the GUI.
** For thread safety, this method should be invoked from the event-dispatching thread.
**/
private static void createAndShowGUI() {
// Create and set up the window
JFrame frame = new JFrame("Prog340");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create and set up the content pane.
JComponent newContentPane = new Prog340();
newContentPane.setOpaque(true);; // content panes must be opaque
frame.setContentPane(newContentPane);;
// Display the window.
frame.pack();
frame.setVisible(true);
}
/** The constructor creates a new ProgramA object, and sets up the input and output files.
**/
public Prog340() {
super( new BorderLayout() );
try {
// I like the colorful FileChooser.
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
System.out.println( "Look and feel set.");
}
catch (Exception e) { // exit on exception.
System.err.format("Exception: %s%n", e);
System.exit(0);
}
fileChooser = new JFileChooser();
fileChooser.setDialogTitle("Choose a file");
// Start looking for files at the currect directory, not home.
fileChooser.setCurrentDirectory(new File("."));
inputFile = null;
g = new Graph();
// Select the action
comboBoxList = new String[8];
comboBoxList[0] = new String("prog340: Select file and read graph");
comboBoxList[1] = new String("Deliv A: Write Graph Info");
comboBoxList[2] = new String ("Deliv B: Run Heap methods on selected file");
comboBoxList[3] = new String ("Deliv C: TBD");
comboBoxList[4] = new String ("Deliv D: TBD");
comboBoxList[5] = new String ("Deliv E: TBD");
comboBoxList[6] = new String ("Deliv F: TBD");
comboBoxList[7] = new String ("exit");
JComboBox actionList = new JComboBox( comboBoxList );
actionList.setName("Action List");
actionList.setSelectedIndex(0);
actionList.addActionListener( this );
add( actionList, BorderLayout.PAGE_START );
}
// Listen to the Combo Box
public void actionPerformed( ActionEvent e ) {
JComboBox cb = (JComboBox)e.getSource();
String actionName = (String)cb.getSelectedItem();
int actionIndex = cb.getSelectedIndex();
switch( actionIndex ) {
case 0:{
g = new Graph();
readGraphInfo( g );
break;
}
case 1:
DelivA dA = new DelivA( inputFile, g );
break;
case 2:
{
int numElements = 1;
int j =0;
int k;
//rewritten switch statement case to make DelivB combo box work
g = new Graph();
readGraphInfo( g );
DelivB dB = new DelivB(inputFile, g);
h = new Heap(g);
System.out.println("unordered list: \n");
System.out.println(g.toString());
System.out.println("==========================================");
//h.Build_min_Heap(h.getOrdered_nodelist());
for (j = 0; j <= h.getHeapSize(); j++)
//while (j <= h.getHeapSize())
//for (Node n : h.getOrdered_nodelist())
{
//copy node elements from unordered arraylist to new empty arraylist
h.getOrdered_nodelist().add(h.getUnordered_nodelist().get(j));
System.out.println("unordered node list size is: " + h.getUnordered_nodelist().size()+ "\n");
System.out.println("ordered node list size is: " + h.getOrdered_nodelist().size());
System.out.println("\nvalue of j is: " + j + "\n");
System.out.println("Heaps: \n");
h.Build_min_Heap(h.getOrdered_nodelist());
System.out.println("after build heap call: \n" );
System.out.println(h.toString());
//System.out.println("\ngraph class toString method: \n");
//System.out.println(g.toString() + "\n");
//System.out.println(g.toString2());
System.out.println("HeapSort: \n");
h.heap_Sort(h.getOrdered_nodelist());
System.out.println("after heapsort call: \n");
System.out.println(h.toString());
j++;
//System.out.println("\n graph class toString method: \n");
//System.out.println(g.toString() + "\n");
//System.out.println(g.toString2());
//System.out.println("the"+j+"th element in the original array is: \n"+h.getOrdered_nodelist().get(j).getAbbrev());
//System.out.println("the"+j+"th element in the new array is: \n"+h.getUnordered_nodelist().get(j).getAbbrev());
//System.out.println("\n after build heap method call, the output is as follows: " + g.toString());
}
break;
}
case 3:
DelivC dC = new DelivC( inputFile, g );
break;
case 4:
DelivD dD = new DelivD( inputFile, g );
break;
case 5:
DelivE dE = new DelivE( inputFile, g );
break;
case 6:
DelivF dF = new DelivF( inputFile, g );
break;
case 7:
System.out.println( "Goodbye");
System.exit(0);
default:
System.out.println( "Invalid choice" );
System.exit(0);
}
}
/** Read the file containing the Strings, line by line, then process each line as it is read.
**/
public void readGraphInfo( Graph g ) {
try {
if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
// Instantiate the selected input and output files.
inputFile = fileChooser.getSelectedFile();
System.out.println( "Chosen file = " + inputFile + "\n");
}
// read text file
Scanner sc = new Scanner( inputFile );
// First line special: It contains "~", and "val", and the nodes with the edges.
String firstLine = sc.nextLine();
String[] splitString = firstLine.split( " +" );
// Ignore first two fields of first line, Every other field is a node.
for ( int i = 2; i < splitString.length; i++ ) {
Node n = new Node( splitString[i] );
g.addNode( n );
}
// Every other line gives the name and value of the Node, and any edges.
int nodeIndex = 0;
ArrayList<Node> nodeList = g.getNodeList();
while ( sc.hasNextLine() ) {
String nextLine = sc.nextLine();
splitString = nextLine.split(" +");
Node n = nodeList.get( nodeIndex );
n.setName( splitString[0] );
n.setVal( splitString[1] );
for ( int i = 2; i < splitString.length; i++ ) {
if ( !splitString[i].equals("~") ) {
Node head = nodeList.get(i-2);
Edge e = new Edge( n, head, splitString[i] );
g.addEdge( e );
n.addOutgoingEdge( e );
head.addIncomingEdge( e );
}
}
nodeIndex++;
}
sc.close();
}
catch (Exception x) {
System.err.format("ExceptionOuter: %s%n", x);
}
}
}
I have oriented graph and I have to find the shortest path between Q pairs of nodes (A,B). But the path must go over max. N edges and length of these edges must be increasing (from A to B (1,3,5,9)).
Output is length of this path. (If it doesn't exist, output -1).
I tried to represent the graph as 3D arraylist and then recursive find the shortest path, which fill conditions, but I don't know what is wrong.
This code don't work, it is infinity recursion:
public static int path(int v, int c, int mv, int dc, int pv) {
if (pv==mv) {
if (Gi.get(v).contains(c)) {
return G.get(v).get(c).get(0);
}
return -1;
}
bol[v]=true;
for (int i=0; i<G.get(v).size(); i++) {
for (int j=0; j<G.get(v).get(i).size(); j++) {
if (!bol[Gi.get(v).get(i)]) {
if (G.get(v).get(i).get(j)>dc) {
int ce=path(Gi.get(v).get(j),c,G.get(v).get(i).get(j),dc,pv+1);
if (ce!=-1) return ce;
}
}
else {
return -1;
}
}
}
return vz;
}
Can someone help me?
Thanks, Ferko
You can do it with a Min Priority Queue and a single-linked-list data structure representing the path:
import java.util.LinkedList;
import java.util.PriorityQueue;
public class DijkstraTest
{
public static PathSegment Dijkstra(
final Vertex from,
final Vertex to,
final int maxSize
)
{
if ( from == null )
throw new IllegalArgumentException( "From vertex cannot be null" );
if ( to == null )
throw new IllegalArgumentException( "To vertex cannot be null" );
if ( maxSize <= 0 )
throw new IllegalArgumentException( "Maximum size must be at least 1" );
final PriorityQueue<PathSegment> queue = new PriorityQueue<>();
for ( final Edge e : from.outEdges )
queue.add( new PathSegment( e, null ) );
while ( !queue.isEmpty() )
{
final PathSegment p = queue.poll();
final Edge e = p.edge;
final Vertex v = e.to;
if ( v == to )
{
// Found a path to destination
return p;
}
if ( p.size == maxSize )
{
// Not reached the destination but at max length so discard this path
continue;
}
for ( final Edge o : v.outEdges )
{
if ( o.length > e.length ) // Increasing edges
{
queue.add( new PathSegment( o, p ) );
}
}
}
return null;
}
public static class Vertex{
public final int index;
public final LinkedList<Edge> outEdges = new LinkedList<>();
public Vertex( final int i )
{
index = i;
}
}
public static class Edge{
public final Vertex from;
public final Vertex to;
public final int length;
public Edge( final Vertex f, final Vertex t, final int l )
{
from = f;
to = t;
length = l;
from.outEdges.add( this );
}
}
public static class PathSegment implements Comparable<PathSegment>{
public final Edge edge;
public final PathSegment prev;
public final int length;
public final int size;
public PathSegment( final Edge e, final PathSegment p )
{
edge = e;
prev = p;
size = ( prev == null ? 0 : prev.size ) + 1;
length = ( prev == null ? 0 : prev.length ) + edge.length;
}
#Override
public int compareTo( final PathSegment p )
{
return Integer.compare( length, p.length );
}
#Override
public String toString(){
return ( prev == null ? Integer.toString( edge.from.index ) : prev.toString() )
+ ','
+ Integer.toString( edge.to.index );
}
}
public static void main( final String[] args )
{
final Vertex[] vertices = {
new Vertex(1), new Vertex(2), new Vertex(3), new Vertex(4), new Vertex(5), new Vertex(6)
};
final Edge[] edges = {
new Edge(vertices[0],vertices[1],2),
new Edge(vertices[0],vertices[2],7),
new Edge(vertices[0],vertices[5],5),
new Edge(vertices[1],vertices[0],11),
new Edge(vertices[1],vertices[2],3),
new Edge(vertices[2],vertices[3],8),
new Edge(vertices[2],vertices[4],1),
new Edge(vertices[3],vertices[1],10),
new Edge(vertices[3],vertices[4],6),
new Edge(vertices[5],vertices[3],4),
new Edge(vertices[5],vertices[3],7)
};
PathSegment p;
p = Dijkstra( vertices[0], vertices[3], 2 );
System.out.println( p + " - length: " + (p==null?"null":p.length) );
p = Dijkstra( vertices[2], vertices[0], 2 );
System.out.println( p + " - length: " + (p==null?"null":p.length) );
p = Dijkstra( vertices[2], vertices[0], 3 );
System.out.println( p + " - length: " + (p==null?"null":p.length) );
}
}
This outputs:
1,6,4 - length: 12
null - length: null
3,4,2,1 - length: 29
I am trying to implement a sorting function into this code which creates a doubly-linked list.
I don't know where to start other than adding "implements Comparable". After that, I'm simply at a loss for what to do next.
public class MyLinkedList<AnyType> implements Comparable<AnyType>, Iterable<AnyType>
{
private int theSize;
private Node<AnyType> beginMarker;
private Node<AnyType> endMarker;
public MyLinkedList( )
{
clear( );
}
private static class Node<AnyType>
{
public Node( AnyType d, Node<AnyType> p, Node<AnyType> n )
{
data = d; prev = p; next = n;
}
public AnyType data;
public Node<AnyType> prev;
public Node<AnyType> next;
}
public void clear( )
{
beginMarker = new Node<AnyType>( null, null, null );
endMarker = new Node<AnyType>( null, beginMarker, null );
beginMarker.next = endMarker;
theSize = 0;
}
public int size( )
{
return theSize;
}
public boolean isEmpty( )
{
return size( ) == 0;
}
public boolean add( AnyType x )
{
add( size( ), x );
return true;
}
public void add( int idx, AnyType x )
{
addBefore( getNode( idx, 0, size( ) ), x );
}
private void addBefore( Node<AnyType> p, AnyType x )
{
Node<AnyType> newNode = new Node<AnyType>( x, p.prev, p );
newNode.prev.next = newNode;
p.prev = newNode;
theSize++;
}
public AnyType get( int idx )
{
return getNode( idx ).data;
}
public AnyType set( int idx, AnyType newVal )
{
Node<AnyType> p = getNode( idx );
AnyType oldVal = p.data;
p.data = newVal;
return oldVal;
}
private Node<AnyType> getNode( int idx )
{
return getNode( idx, 0, size( ) - 1 );
}
private Node<AnyType> getNode( int idx, int lower, int upper )
{
Node<AnyType> p;
if( idx < lower || idx > upper )
throw new IndexOutOfBoundsException( "getNode index: " + idx + "; size: " + size( ) );
if( idx < size( ) / 2 )
{
p = beginMarker.next;
for( int i = 0; i < idx; i++ )
p = p.next;
}
else
{
p = endMarker;
for( int i = size( ); i > idx; i-- )
p = p.prev;
}
return p;
}
public AnyType remove( int idx )
{
return remove( getNode( idx ) );
}
private AnyType remove( Node<AnyType> p )
{
p.next.prev = p.prev;
p.prev.next = p.next;
theSize--;
return p.data;
}
public String toString( )
{
StringBuilder sb = new StringBuilder( "[ " );
for( AnyType x : this )
sb.append( x + " " );
sb.append( "]" );
return new String( sb );
}
public java.util.Iterator<AnyType> iterator( )
{
return new LinkedListIterator( );
}
private class LinkedListIterator implements java.util.Iterator<AnyType>
{
private Node<AnyType> current = beginMarker.next;
private boolean okToRemove = false;
public boolean hasNext( )
{
return current != endMarker;
}
public AnyType next( )
{
if( !hasNext( ) )
throw new java.util.NoSuchElementException( );
AnyType nextItem = current.data;
current = current.next;
okToRemove = true;
return nextItem;
}
public void remove( )
{
if( !okToRemove )
throw new IllegalStateException( );
MyLinkedList.this.remove( current.prev );
okToRemove = false;
}
}
public int compareTo(AnyType other)
{
return this.compareTo(other);
}
Usually you would want your list to implement the Collection interface and the items in the list to implement Comparable (which involves implementing compareTo() in any type you add to the list). You could strongly type this by requiring that list element types implement Comparable. A short cut may be to extend another Collection type such as LinkedList, and enhance it with the reverse list.
As a general rule though, if have a look for someone else's doubly linked list implementation. Maybe try Google's Guava library? - http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained
A linked list is about the worst possible data structure to sort. One easy approach
(which may be seen as a cheat) is to map the list into an array, sort the array, then
reconstruct the list.
If you must implement the whole sort algorithm (for your class?) then each one has a basic
sorting primitive, usually "exchange" which you have to implement.
In any case, watch out for the identity of the root element of the list.
I've got a program that goes through and reads "tokens" that can either be a String (Symbol) or a number. It uses postfix and a stack to evaluate simple commands.
For example:
/x 100 def
/y 200 def
x y add
should return 300. The first line defines a variable called "x" and sets it to 100. To do this a reader adds "/x" and "100" on the stack and stops when it gets to the "def" operator, which tells it to go make a token with a Symbol called "x" and its value being 100. The stack is then empty, and next time "x" would be pushed, the interpreter should automatically replace it with its value. This is where my problem lies.
This is my interpreter:
while ( r.hasMoreTokens() ) {
Token t = r.nextToken();
if ( !t.isSymbol() ) {
operands.push( t );
} else if (env.contains(t.getSymbol())) {
Token tmp = env.get(t.getSymbol());
operands.push(tmp);
} else if (t.getSymbol().startsWith("/")) {
operands.push(t);
} else if ( t.getSymbol().equals( "def" ) ){
execute_def();
} else if ( t.getSymbol().equals( "add" ) ) {
execute_add();
} else if ( t.getSymbol().equals( "sub" ) ) {
execute_sub();
} else if ( t.getSymbol().equals( "mul" ) ) {
execute_mul();
} else if ( t.getSymbol().equals( "exch" ) ) {
execute_exch();
} else if ( t.getSymbol().equals( "dup" ) ) {
execute_dup();
} else if ( t.getSymbol().equals( "pop" ) ) {
execute_pop();
} else if ( t.getSymbol().equals( "pstack" ) ) {
execute_pstack();
} else if ( t.getSymbol().equals( "moveto" ) ) {
execute_moveto();
} else if ( t.getSymbol().equals( "lineto" ) ) {
execute_lineto( g );
} else if ( t.getSymbol().equals( "arc" ) ) {
execute_arc( g );
} else if ( t.getSymbol().equals( "quit" ) ) {
execute_quit();
} else {
System.out.println( "ILLEGAL SYMBOL: " + t );
}
}
Once the variables get defined correctly, I cant get into that first else if and change the value. Because I can't do this, I never push anything on the stack and end up with an empty stack error. Here are the methods contains() and get() from env (environment):
public boolean contains(String key) {
Elem tmp = top;
for (int i = 0; i < size; i++) {
if (tmp.key == key) {
return true;
} else {
tmp = tmp.next;
}
}
return false;
}
public Token get(String key) {
Elem tmp = top;
int counter = 0;
boolean found = false;
for (int i = 0; i < size; i++) {
if (tmp.key == key) {
found = true;
break;
} else {
tmp = tmp.next;
}
counter++;
}
if (found == true) {
tmp = top;
for (int i = 0; i <= counter; i++) {
tmp = tmp.next;
}
return tmp.value;
} else {
throw new BadKeyQueryException();
}
}
I'm using linked elements in the environment to keep track of symbols. Elem is a nested class in Environment:
private static class Elem {
private String key;
private Token value;
private Elem next;
private Elem(String key, Token value, Elem next) {
this.key = key;
this.value = value;
this.next = next;
}
}
Thanks for any help from you guys!
Strings in java are Objects, rather than primitives.
When you say:
int i = 5;
i stores the value "5".
When you say:
String s = "string";
s stores the value of a reference to "string".
Comparing s to "string" would return false, even though they contain the same value when you print there. This is because the computer compares a reference to memory containing "string" to another reference to memory containing "string". Same values, but different references.
Also, you're setting "t" to multiple different values in your code. Try setting t once, before everything, and a precomputed t value against your if-else-if block.
You can only call getSymbol() once, so you just need to store the value from it. Here is the start of your statements, you should be able to change the others the same way
if ( !t.isSymbol() ) {
operands.push( t );
continue;
}
String symbol = t.getSymbol();
if (env.contains(symbol)) {
Token tmp = env.get(symbol);
operands.push(tmp);
} else if (symbol.startsWith("/")) {
operands.push(t);
...