Depth First Search is causing a StackOverFlowError - java

I have an assignment were I have to create run a depth first search through a directed graph, and return the traversal as a linked list. I believe the code for the DFS is correct as it seems to match up with the text book, and as I walk through the steps it makes sense. If I print it out as each vertex gets marked, it keeps printer over and over causing the stack overflow error.
private static boolean[] marked;
private static LinkedList<Integer> ret;
public static LinkedList<Integer> dfs(Digraph g, int s) {
marked = new boolean[g.V()];
ret = new LinkedList<>();
marked[s] = true;
System.out.print(s);
ret.add(s);
for (int i : g.adj(s)) {
if (!marked[i]) {
dfs(g, i);
}
}
return ret;
}
My guess would be the boolean[] marked is reseting every time I call dfs. I tried putting that outside the method but because the method is static and I can't change it(given the assignment parameters), I was getting a static-non static issue which I'm not quite sure how to fix.

Yup, your issue was indeed because the boolean was being reset in a sense. The resetting was happening in this line:
marked = new boolean[g.V()];
On this line, you are creating a new boolean array in the new function call, which is distinct from the original array . Then you are checking the new array which does not contain the changes from the old array.
I would recommend that you create a wrapper function that initializes the dfs process, and then pass the array into each call of your dfs function.
If you do not want to add extra parameters, just create a static variable as such outside of the method:
private static boolean[] marked;
Then initialize it when appropriate

Related

Using an array in a recursive algorithm to find combinations

The idea is if i am at a certain stair i can either go one step down or two so if am at stair 3 i can go down 1 1 1 or 2 1 for example. My code should print all the possibilities. The error I get is that I can't convert the add function to an array (since the add method is a boolean). What is wrong with this algorithm?
public class Stairs {
public static void staircase (int height ){
ArrayList<Integer> Array = null;
explore (height,Array);
}
public static void explore(int objheight,ArrayList<Integer>Array){
int intialheight = 0;
if (intialheight == objheight){
Array.toString();
}
else{ if (objheight > intialheight ){
explore(objheight-2,Array.add(2));
explore(objheight-1,Array.add(1));
}
}
after your feedback I am getting an empty output
import java.lang.reflect.Array;
import java.util.ArrayList;
public class Stairs {
public static void staircase (int height ){
ArrayList<Integer> Array = new ArrayList<Integer>();
explore (height,Array);
}
public static void explore(int objheight,ArrayList<Integer>Array){
int intialheight = 0;
if (intialheight == objheight){
Array.toString();
}
else{ if (objheight > intialheight ){
Array.add(2);
explore(objheight-2,Array);
Array.add(1);
explore(objheight-1,Array);
}
}}
public static void main (String args[]){
staircase(3);
}
}
The method add(E e) in ArrayList returns true upon appending the element e passed as a parameter to the end of the ArrayList.
Your method, explore(int objHeight, ArrayList<Integer> Array) does not accept a boolean for its second parameter. Yet, in that same method, explore, you are recursively calling explore and passing in a boolean to the method.
The following code should be modified to first invoke the add method of Array and then pass Array to the explore method.
Before:
explore(objheight-2,Array.add(2)); This code is passing parameters int and boolean to the explore method, which is not the parameters it accepts. You should instead attempt the following.
After:
Array.add(2);
explore(objheight-2,Array); This code first adds 2 to the Array and then passes the Array to the explore method without invoking any further methods on the Array object.
You will also need to do this for the next line of code, where you have explore(objheight-1,Array.add(1));.
Edit: Upon further examination of the code, I discovered another (sooner) error that occurs. A NullPointerException will occur each time the program runs:
ArrayList<Integer> Array = null;
explore (height,Array);
Then inside the explore method, different methods on Array are invoked, despite Array always being null:
Array.toString();, Array.add(2) and Array.add(1).
The Array object must be initialized inside of either the staircase or explore methods.
ArrayList<Integer> Array = new ArrayList<Integer>(); or ArrayList<Integer> Array = null;
Array = new ArrayList<Integer>();

Reversing an ArrayList (Understanding the code)

I found an exercise in a book that adds some money into an ArrayList, and then reverses them. I know we can easily use Collection.reverse(), which is what my textbook shows, but I found another cool solution online that I am trying to understand but having trouble with.
Heres the code:
class Purse {
private ArrayList<String> coins = new ArrayList<String>();
public void addCoin(String coinName) {
coins.add(coinName);
}
public void reverse() {
for(int start = 0, end = coins.size() - 1; start < coins.size() / 2; start++, end--) {
swap(start,end,coins);
}
}
private void swap(int starting, int ending, List aList) {
Object temp = aList.set(starting, aList.get(ending));
aList.set(ending,temp);
}
public String toString() {
return "Purse: " + coins;
}
}
public class PurseDemo {
public static void main(String [] args) {
Purse purseObj = new Purse();
purseObj.addCoin("Quarter");
purseObj.addCoin("Dime");
purseObj.addCoin("Penny");
purseObj.addCoin("Nickel");
System.out.println(purseObj);
purseObj.reverse();
System.out.println(purseObj);
}
}
Here is where my confusion is:
Object temp = aList.set(starting,aList.get(ending));
aList.set(ending,temp);
First of all, I think I get the idea of this. However, this is my first time seeing the Object keyword. What I don't really get is what temp actually represents ( I got this code off online, in my book they havent introduced this keyword Object yet)
Here are my thoughts on an example iteration
Suppose our arrayList has
[Quarter,Dime,Penny,Nickel]
According to Object temp = aList.set(starting,aList.get(ending));
We take the the first spot in the ArrayList Quarter and put the value of nickel in there. So we get the ArrayList
[Nickel,Dime,Penny,Nickel]
Now I'm kind of confused.. When I system.out.println(temp), it tells me the values are Quarter and Dime. But why? Can someone go through an example iteration with me?
AFTER READING ANSWER
[Quarter,Dime,Penny,Nickel]
Nickel replaces Quarter, thus temp is Quarter. So we add Quarter to the end
I.E we get
Quarter,Dime,Penny,Quarter
Wait.. But where did our nickel go?!
The set() method returns the object that is being displaced by the new object. The first line
Object temp = aList.set(starting,aList.get(ending));
is the same as:
Object temp = aList.get(starting);
aList.set(starting, aList.get(ending));
You could actually do it without the temp variable, in one line:
aList.set(ending, aList.set(starting, aList.get(ending)));
The swap method can be translated into its "usual form":
Object temp = aList.get(starting);
aList.set(starting, aList.get(ending));
aList.set(ending, temp);
All the code you found does is combine the first two lines because List.set promises to return the replaced value.
Now let's see your example, where aList initially is [Quarter,Dime,Penny,Nickel], and starting is 0 and ending is 3.
Object temp = aList.get(starting);, now temp is Quarter.
aList.set(starting, aList.get(ending));, now aList is [Nickel,Dime,Penny,Nickel].
At last, aList.set(ending, temp);, sets the last element of aList to Quarter: [Nickel,Dime,Penny,Quarter]

Passing a parameter into a method on a constructor

I have a problem that is pretty basic but I am struggling to get right. Basically, I have a constructor that has some methods defined on it using this.. I want to pass one of those methods a paramter, but I am struggling to declare it in a way that doesn't cause an error. This is my code:
public class Graph {
public Graph(int[][] gA) {
boolean[] visited = new boolean[gA.length];
Arrays.fill(visited, 0, gA.length, false);
//this is the bit I'm struggling with:
this.adj(int v) = gA[v];
this.array = gA;
this.visited = visited;
}
}
How do I get this.adj to accept a parameter? I also tried creating a method declaration but couldn't get this work either. Is there some kind of design pattern I should use?
Thanks
EDIT: Apologies - made a mistake in the code excerpt. this.adj[v] should be returning a row of the gA array, which it only has access to within the constructor, so I cannot move the function outside.
This :
this.adj(int v) = adj(v);
Is the wrong way. Just use:
adj(v); // Call the method adj with the parameter v
Since you are calling it in the constructor, hence it does not matter if the method is static or not. A constructor can call both of them.
Edit:
I want adj[v] to return the row of gA at v. I've edited the code above
You can do:
gA[v] = adj(v);
why you dont just call the method you defined??
public class Graph {
private YOUR_TYPE adj;
public Graph(int[][] gA) {
boolean[] visited = new boolean[gA.length];
Arrays.fill(visited, 0, gA.length, false);
//this is the bit I'm struggling with:
this.adj = adj(v);
this.array = gA;
this.visited = visited;
}
YOUR_TYPE adj(int v){
return .... something from YOUR_TYPE
}
}

Recursive Tree Traversal Method With Return Type Array

Is there a way to recursively traverse a tree and return an array that is scoped to that recursive method?
So I recently answered someone else's question on this topic. That question can be found here: SO Question. My solution uses an array outside of the scope of the recursion, and therefore the method cannot (or at least probably should not) return the array. However, is there a way to write a recursive method for traversing trees such that it returns an array? Even writing an initial method that calls the recursive one would be fine, but I can't think of a good way to do this.
Here's the code that I suggested before:
private List nodeValues = new ArrayList();
public void traversePreRecursive(BinarySearchTreeNode node)
{
if (node != null)
{
nodeValues.add(node.getValue());
traversePreRecursive(node.getLeft());
traversePreRecursive(node.getRight());
}
}
As you can see the ArrayList is outside of the scope of the recursion - And therefore returning it doesn't make a lot of sense. Is there a better way to do this?
public static List traversePreRecursive(Node node) {
if (node == null) return new ArrayList();
List nodeValues = new ArrayList();
nodeValues.add(node.getValue());
nodeValues.addAll(traversePreRecursive(node.getLeft()));
nodeValues.addAll(traversePreRecursive(node.getRight()));
return nodeValues;
}
There is an alternative, but it involves two passes over the tree. You would only employ this alternative if the array operations in my first answer were giving you grief. This approach starts by providing an index for each of the nodes (the index() method) -- basically working out which element of the array a node should occupy before we actually create the array. This also gives me a count of nodes (size). I then allocate an array (list) big enough to hold all the nodes and pass it into a method (addToList) that copies the node-references into the previously identified element in the array.
public static List<Node> getNodes(Node a) {
int size = index(a, 0);
List<Node> list = new ArrayList<Node>(size);
addToList(a, list);
return list;
}
private static int index(Node node, int index) {
if (node == null) return index;
node.setIndex(index);
int iLeft = index(node.getLeft(), index++);
int iRight = index(node.getRight(), iLeft++);
return iRight + 1;
}
private static void addToList(Node node, List<Node> list) {
if(node == null) return;
list.add(node.getIndex(), node);
addToList(node.getLeft(), list);
addToList(node.getRight(), list);
}
In c you can have static function variables,(Ie, adding a value to a list in one iteration of a function means that that value will be in the list in the next iteration--if the list is static) but using them isn't the best (most optimal) solution for the problem you are suggesting. So, I think you are searching for static variables, but this isn't an appropriate case to use them.

How to create extensible dynamic array in Java without using pre-made classes?

Yeah, it's a homework question, so givemetehkodezplsthx! :)
Anyway, here's what I need to do:
I need to have a class which will have among its attributes array of objects of another class. The proper way to do this in my opinion would be to use something like LinkedList, Vector or similar. Unfortunately, last time I did that, I got fire and brimstone from my professor, because according to his belief I was using advanced stuff without understanding basics.
Now next obvious solution would be to create array with fixed number of elements and add checks to get and set which will see if the array is full. If it is full, they'd create new bigger array, copy older array's data to the new array and return the new array to the caller. If it's mostly empty, they'd create new smaller array and move data from old array to new. To me this looks a bit stupid. For my homework, there probably won't be more that 3 elements in an array, but I'd like to make a scalable solution without manually calculating statistics about how often is array filled, what is the average number of new elements added, then using results of calculation to calculate number of elements in new array and so on.
By the way, there is no need to remove elements from the middle of the array.
Any tips?
class test {
private Object[] objects;
private int size;
public test() {
objects = new Object[10];
size = 0;
}
public void push(Object o) {
if (objects.length == size) {
throw new RuntimeException("This wouldn't happen if I didn't have to reinvent the wheel");
}
objects[size] = o;
size++;
}
public Object pop() {
size--;
Object o = objects[size];
objects[size] = null;
return o;
}
}
Just kidding. I think you're best bet is to implement your own linked list and then use that in your class. Something like:
class Element {
Object val;
Element next;
Element prev;
public Element(Object val, Element next, Element prev) {
this.val = val;
this.next = next;
this.prev = prev;
}
}
class LinkedList {
Element head;
Element tail;
public void add(Object o) {
Element el = new Element(o, null, tail);
tail.next = el;
}
public Object remove() {
Element o = tail;
tail = o.prev;
tail.next = null;
return o.val;
}
}
One thing you will want to do is when you need to grow the size of your array create an array that is twice the size of the old array. Likewise, if you need to shrink the size of hte array, only do it once the array is half full.
This will make it so you have to do far less array copies.
Doing this will make it necessary to keep a variable that keeps track of the actual size of the array because the length of the array will not accurately represent the actual size.
To copy an existing array into a smaller or larger one, you may find System#arrayCopy() useful.
Kickoff example:
Object[] originalArray = new Object[3];
// ...
Object[] resizedArray = new Object[originalArray.length + 2]; // Grow with 2.
System.arrayCopy(originalArray, 0, resizedArray, 0, originalArray.length);
This will copy the items over the entire length of originalArray into the beginning of resizedArray. The 2 slots at end of resizedArray are still null so that you can use it for other items.
This must get you started. Good luck :)
Is it for a data structures class ? Sounds like your professor expects you to implement your own Linked List data structure or something similar instead of using the one Java provides. Google and your text book(s) are your friend.
If I recall correctly, the ArrayList class works by having a fixed size array (with an initial capacity of whatever you set) that resizes in pretty much the way you described when it's full.
You could use a linked list, though by the sounds of it your professor wants you to program this stuff by yourself, so create your own class demonstrating you know how it works?
i think its really easy way :p which we cant do in C but can do in java
package javaapplication21;
import java.util.Scanner;
public class JavaApplication21 {
public static void main(String[] args) {
int a;
Scanner obj=new Scanner(System.in);
System.out.print("Enter array size=");
a=obj.nextInt();
int b[]=new int[a];
for(int i=0;i<b.length;i++){
System.out.println(b[i]+i);
}
}
}

Categories

Resources