Recursive Java, Checking for conflicts between nodes - java

I am trying to configure out a method for checking conflicts between the head and all of the other nodes. At this point, I'm getting stuck in a loop. Any idea how to loop through the list, comparing head with head.next .next .next.next and so on?
EDIT: After adding a return false; after the conflictCheck(a,b.getNext()), there is no longer the loop problem but the output reflects this method NOT comparing each node with the head node.
EDIT X 2! : I believe I have the loop checking for conflicts working fine thanks to everyone who commented/answered. Now I have strange results in my program,where conflicts are being detected but nothing is being done about them. I've added my other important method that deals with these shenanigans. Also, my output is below. Is there any reason why Every node's column is moving to either 3, or staying at 1???
public static void playChess() {
System.out.println("Playing chess");
if (conflictCheck(head, head.getNext())) {
if (head.getColumn() == 8) {
queens.pop();
}
else if (!queens.isEmpty() && head.getColumn()!= 8) {
System.out.println("Adjusting head");
head.setColumn(head.getColumn()+1);
System.out.println("Head is now " + head.getRow() + ", " + head.getColumn());
playChess();
}
}
else if (queens.size() < 8) {
System.out.println("Stack isn't full yet");
queens.push(queens.size()+1,1);
queens.viewPieces();
playChess();
}
else {
success= true;
System.out.println("Success");
queens.viewPieces();
return;
}
}
public static boolean conflictCheck(QueenNode a, QueenNode b) {
//checks for conflicts between head and all other nodes in the stack
a= head;
while (b != null) {
if (a.getRow()!=b.getRow() && a.getColumn()!=b.getColumn() && !diagonal(a,b)){
conflictCheck(a,b.getNext());
}
else {
System.out.println("There is a conflict");
return true;
}
}
return false;
}
My output
Playing chess
Comparing 8 ,3 And 7 , 1
There is a conflict with 8,3 And 6,3
Success
The stack
8, 3
7, 1
6, 3
5, 1
4, 3
3, 1
2, 3
1, 1
End of stack

You're mixing the cycle with the recursive call.
If I understand you correctly, you would want something like:
public static boolean conflictCheck(QueenNode a, QueenNode b) {
//checks for conflicts between head and all other nodes in the stack
if (b == null){
return false;
}
if (a.getRow()!=b.getRow() && a.getColumn()!=b.getColumn() && !diagonal(a,b)){
return conflictCheck(a,b.getNext());
}
else {
System.out.println("There is a conflict");
return true;
}
}
I didn't run the code, so I'm hoping you get the picture, there's probably a syntax error or 4.

EDIT: As noted above, you also need a condition to end the recursion which I didnt include here - test if b is null sounds right.
The recursive call doesn't look right.
You would need to setup your initial a and b variable inside the block calling this recursive method, not inside the recursive method.
//...
a = nodes.head;
b = nodes.getNext();
if(conflictCheck(a, b)) {
//... there is a conflict
}
and then your method should look something like :
public static boolean conflictCheck(QueenNode a, QueenNode b) {
if (a.getRow()!=b.getRow() && a.getColumn()!=b.getColumn() && !diagonal(a,b)){
// there is no conflict here, check one step further into the list and return the result
return conflictCheck(a,b.getNext());
}
else {
// there is a conflict, stop here
System.out.println("There is a conflict");
return true;
}
}
HTH

Related

I am having trouble with returning in depth first search

I am working on an algorithm that finds a path in a hexagon grid. For this I am using depth first search with a depth of 3. It works in the sense that it finds the correct path. The only problem is that it does not return it. Instead it returns an empty set.
public Set findPath(Game game, Point origin, Point destination, Set<Point> hasVisited, int depth) throws Exception {
if (origin.equals(destination)){
System.out.println("Return from goal requirements: " + hasVisited);
return hasVisited;
}
if (!origin.equals(destination)){
if (depth != 0) {
for (Point emptyNeighbor : getEmptyNeighbors(game, origin)) {
if (!hasVisited.contains(emptyNeighbor)) {
if (!game.isHiveBrokenAfterPush(origin, emptyNeighbor)) {
hasVisited.add(emptyNeighbor);
game.push(origin.x, origin.y, emptyNeighbor.x, emptyNeighbor.y);
findPath(game, emptyNeighbor, destination, actualOrigin, hasVisited, depth - 1);
hasVisited.remove(emptyNeighbor);
game.push(emptyNeighbor.x, emptyNeighbor.y, origin.x, origin.y);
}
}
}
}
}
System.out.println("Return from end of function: " + hasVisited);
return hasVisited;
}
After the loads of If statements it adds the node to hasVisited and pushes the piece in the direction. It then calls itself to continue on the branch of the tree. It removes the node form hasVisited and cancels the push if it does not work out.
What happends right now is that the final return seems to be from the and of the function. These are the last lines it prints:
Return from goal requirements: [java.awt.Point[x=-1,y=0], java.awt.Point[x=-2,y=1], java.awt.Point[x=-2,y=2]]
Return from end of function: [java.awt.Point[x=-1,y=0], java.awt.Point[x=-2,y=1]]
Return from end of function: [java.awt.Point[x=-1,y=0]]
Return from end of function: []
[]
The upper set of coordinates is what it SHOULD return. But it returns an empty set as you can see.
I have tried to return the findPath instead of just executing it. Doing that it only does one branch. It doesn't cancel moves that don't work. I can't see the problem in my code and hope you guys can help me. Cheers!
If there is just one solution, return immediately.
The recursion adds one element to the set, calls recursively and undoes the adding.
This will alter the set, the result. When collecting more than one result, one would copy the set.
public boolean findPath(Game game, Point origin, Point destination, Set<Point> hasVisited,
int depth) throws Exception {
if (origin.equals(destination)){
System.out.println("Return from goal requirements: " + hasVisited);
return true;
}
if (depth != 0) {
for (Point emptyNeighbor : getEmptyNeighbors(game, origin)) {
if (!hasVisited.contains(emptyNeighbor)) {
if (!game.isHiveBrokenAfterPush(origin, emptyNeighbor)) {
hasVisited.add(emptyNeighbor);
game.push(origin.x, origin.y, emptyNeighbor.x, emptyNeighbor.y);
boolean found = findPath(game, emptyNeighbor,
destination, actualOrigin, hasVisited, depth - 1);
if (found) {
return true;
}
hasVisited.remove(emptyNeighbor);
game.push(emptyNeighbor.x, emptyNeighbor.y, origin.x, origin.y);
}
}
}
}
System.out.println("Not found");
return false;
}

Return in case of Recursive call to a method

I have a piece of code that I need insight on, I don't want to know the correct solution of the problem. I just want to know why is my concept failing.
So the function is to check if a binary tree is BST or not. I need to return 1 in case it is and 0 otherwise. My code is as below
int isBST(Node root) {
if(root == null)
return 1;
if(root.left!=null) {
if(root.left.data<root.data)
isBST(root.left);
else
return 0; // line:a
}
if(root.right!=null) {
if(root.right.data<root.data)
isBST(root.right);
else
return 0;
}
return 1;
}
For this piece, when i have a binary tree as follows:
5
\
7
/
8
I expect it to reach 8 value and break at line:a but it return me 1 instead of 0. Now I know 0 gets returned to the parent calling method. But is it not terminating because I have made isBST call without capturing the return value?
Please dont point out if there are anyother bugs.
For the general case, your approach won't work. The way to test if a tree is a BST is to recursively check if the current node is greater than the maximum element of the left subtree, and smaller than the minimum element of the right subtree. Also, you're missing the returns in the recursive calls:
return isBST(root.left);
...
return isBST(root.right);
By the way, why are you returning 0 or 1 for this? use false or true instead, changing the return type to boolean.
You should check if the right data ist bigger than the current and return the value of the recursive call
if(root.right.data>root.data)
I see the following issues:
If (and only if) isBST(root.left) or isBST(root.right) is false, you need to return 0 (btw, why are you not using booleans?) immediately.
The condition root.right.data<root.data should be inverted: root.right.data>=root.data.
So here's the modified code (keeping the int return type):
int isBST(Node root) {
if(root == null)
return 1;
if(root.left!=null) {
if(root.left.data<root.data) {
if (isBST(root.left) == 0)
return 0;
} else
return 0;
}
if(root.right!=null) {
if(root.right.data>=root.data) {
if (isBST(root.right) == 0) {
return 0;
}
} else
return 0;
}
return 1;
}

Break statement always gets executed

This might be a stupid question but we're beginners and I didn't find an answer to my problem so here it is: We're developping a file system (small based) and we have this method that is supposed to move files from one Directory to another. (Deleting the file or directory from one and adding to another.)
We're using ArrayLists to store the Items (Item is then superclass of Directory and File).
Because of the fact that everything has to be sorted alphabetically, the method to move contains a while loop to verify where the item has to be placed (no preferences to Directories or Files) but for some reason the break statement I inserted is ALWAYS executed (or at least that's what I think is the reason.) Thanks!
Here's the code:
if(item != null){
boolean bool = false;
int i = 0;
loop: while(!bool && i <= items.size()-1) {
if(i==0) {
if(checkIfAlphabetic(item.getName(), items.get(0).getName())){ items.add(0,item);
bool = true;
}
else{
break loop;
}
}
else if(checkIfAlphabetic(items.get(i-1).getName(), item.getName()) && checkIfAlphabetic(item.getName(), items.get(i).getName() )) {
items.add(i, item);
bool = true;
}
else i++;
}
if(!bool){
items.add(item);
}
setModificationTime();
}
I already excuse myself if there are some things unclear.
PS. Also for some reason the Item I want to add always gets added twice.
As requested, the code for checkIfAlphabetic:
private boolean checkIfAlphabetic(String search, String target){
int[] searchInt = search.codePoints().toArray();
int[] targetInt = target.codePoints().toArray();
int i = 0;
while(i<search.length() && i<target.length()){
if(searchInt[i] > targetInt[i]){
return false;
}
else if(searchInt[i] < targetInt[i]) return true;
else i++;
}
if(search.length() < target.length()){
return true;
}
else return false;
}
Your while loop is faulty. It will always stop after the first iteration, no matter what.
This is what happens in order of statements. This is pseudo-code, not Java. Don't copy/paste, it won't work.
boolean bool = false;
int i = 0;
// entering the while loop:
if (!bool && i <= items.size() - 1) // returns true. We go in the while loop.
if (i == 0) // returns true, we go in that block.
if (check... ) // if this returns true, this happens:
bool = true;
else // if the previous statement returns false, this happens:
break;
So here, if the check... returns false, we're gonna get out of the loop. Let's continue in the other case:
// nothing else happens inside the loop, so go back to the loop condition.
if (!bool && i <= items.size() - 1) // Hey, wait a minute, bool is true. So "not" true is false. The condition is therefore not met, let's leave the loop.
So this is what happens, after a single execution, no matter what, your code exits the loop. In your scenario, bool = true is the near absolute equivalent to a break.
This is what you need to fix.
If I had to write your code, this is how I'd do it:
List<Item> items = ... ;
java.util.Collections.sort(items, new ItemNameComparator());
private static class ItemNameComparator implements Comparator<Item> {
#Override
public int compare(Item a, Item b) {
return a.getName().compareTo(b.getName());
}
}
If you use Java 8:
List<Item> items = ...;
items.sort((a, b) -> a.getName().compareTo(b.getName()));
All the tools exist in the Java libraries, use them instead of reimplementing them again and again.

Can I manipulate the way that variables change in Java?

If the die shows a 6, the player doesn't move at all on this turn and also forfeits the next turn.
To accomplish this, I have tried an integer type warning marker variable for the player and an integer type time counter variable.
If the die shows 6, I want to increment the warning marker variable by 1 during the first run(and have the while loop do nothing), then keep the value at 1 during the second run (while loop will not work), then lower it back down to 0 for the third run of the while loop (so the while loop will work). The marker will stay at zero unless the die shows a 6 again, after which the same process will repeat.
I have a while loop like this:
while the warning marker is equal to 0 {
Do Stuff
if the die shows a 6, the warning marker increases by 1.
the time counter also increases by 1.
}
How do I manipulate the variables to get the result that I need? Or is my partially complete method absolutely off in terms of logic?
Thanks.
Can u tell me if this works for you?
flag=true;
while condition{
if flag==true{
if die == 6
{
flag=false;
continue;}
}
else { Do STUFF }
} else
{
flag==true;
}
}
I think you want to reword this problem.
This is what I understood. You have a warning marker.
You have a loop that checks whether the marker is 0, if it is then you do something.
If the die is a six, you will increase the warning marker. If its new value is 3, then you will reset it to 0. Meanwhile, the time counter is always increasing.
If this is correct, I think you want something like:
int warningMarker = 0;
int timeMarker = 0;
while (true) {
if (die == 6) {
++warningMarker;
if (warningMarker == 3) {
warningMarker = 0;
}
}
if (warningMarker == 0) {
doSomething();
}
++timeMarker;
}
Java is Object-Oriented Pragramming language. Use this feature.
See following pseudocode and let me know if you have problem in undestanding it.
Create a class Player as following:
class Player
{
boolean skipChance = false;
... // Other fields
... //
}
Change your while as following:
while(isGameOn())
{
Player p = getCurrentPlayer();
if( ! p.skipChance)
{
int val = p.throwDice();
if(val == 6)
{
p.skipChance = true;
continue; // control moves to while.
}
// Do stuff
}
else
{
p.skipChance = false;
}
}

Recursive method why does it stop?

i am trying to learn abit about recursive methods and is writing a method for my binary tree that counts the sum of all the integers in the tree my code works fine and all but i am still abit confused about how the application knows when to stop. my code looks like the this:
public int sum(){
return sum(overallRoot);
}
private int sum(IntTreeNode root) {
if (root == null) {
return 0;
}else {
return root.data + sum(root.left) + sum(root.right);
}
}
(the above code is from my nodeTree class)
The next code is from my main class:
public class TreeClient {
/**
* #param args
*/
public static void main(String[] args) {
IntTree tree = new IntTree(12);
System.out.println(tree.sum());
}
}
So the question is (maybe for many quite simple) but how does my application know when to stop? ive tried with simple system out prints to figur out but as far as my understanding is right now the method would call it self in an endless loop?
hope someone has time to respond!
In any recursive program, your iteration stops when a base condition is reached.. Here your base condition is : -
if (root == null) {
return 0;
}
So, when your root.left and root.right, in the following return statement in else block both becomes null, you have reached your base condition, and hence your loop stops..
return root.data + sum(root.left) + sum(root.right);
Pretty simple really
Take the line from the sum function:
return root.data + sum(root.left) + sum(root.right);
When you get to the bottom of the tree, root.left will be null, and so will root.right. Thus, when the above line calls sum(root.left) the sum function drops into the other half of the if statement:
return 0;
Thus, the sum function no longer calls itself, and so stops recursing
The answer is that it does not go into an endless loop because there is a condition when it does not call itself recursively anymore.
The condition is
if (root == null)
when it does
return 0;
rather than calling itself again
return root.data + sum(root.left) + sum(root.right);

Categories

Resources