How to output binary search method? - java

This is just your average binary search, in my program I use this search method to allow the user to look for book titles.
String [] binaryArray = {"4", "6", "10"}; //the chosen binary numbers to look for
public static Boolean binarySearch(String [] A, int left, int right, String V) {
int middle;
Boolean found = false;
while (found == false && left <= right) {
//If middle item == 0, returns true
middle = (left + right)/2;
int compare = A[middle].compareTo(V);
if (compare == 0) {
found = true;
} else {
if (compare >0) {
right = middle -1;
} else {
left = middle + 1;
}
}
}
if (left > right) {
return false;
} else {
return true;
}
}
Now I choose IF statements to output the correct response, but imagine if the database was for a real library with possibly millions of entries. This obviously would not work very well. So what is way a way I can find the response needed without IF statements? Any ideas or advice would be appreciated!
private void findBookActionPerformed(java.awt.event.ActionEvent evt) { //finds book...
String input = enterNumberField.getText(); //input number to see if it matches up
if ("4".equals(input)) {
binarySearchField.setText("Book Title" + binarySearch(binaryArray, 0, binaryArray.length-1, "4"));
} else if("6".equals(input)){
binarySearchField.setText("Book Title" + binarySearch(binaryArray, 0, binaryArray.length-1, "6"));
} else if("10".equals(input)){
binarySearchField.setText("Book Title" + binarySearch(binaryArray, 0, binaryArray.length-1, "10"));
}
}

Related

Node problems with stack implementation of depth first search

If anyone could help me find out what I did wrong, it would be really appreciated. I have taken a few shots at this and have gotten closer with each version of my code. I started by having a linked list within the SearchPath class itself but now I moved it to the Node class. For some reason the code works and finds the end, but it does not properly remove some stuff from the stack. Feel free to give it a try. When the code finishes elements from the stack are supposed to be removed and it does but some extra coordinates end up in there. Not sure if it is because of the way I handled the processing of the already checked nodes or if it the recursion itself. This could also just be a horrible implementation of the problem that needs to be solved and maybe I need to think of another way to solve it, but I know the answer is right there. Possibly also take a look at how I included the linked list and stack as static variables within the node class. Should they have maybe been added elsewhere or could that have been causing some of the issues. Thanks a lot. Also the way it works is by inputting a grid of the same dimensions. Finish is indicated with F and start is indicated with S. The walls are X and the path is O to find the way throught path.
/* This program will implement a stack to try and traverse
a grid from a text file that contains a path. It will try
and find a path to the end and when it does it succeeds.
If it does not find the end that means that there was
not path that exists to it. Reads a file as input.
*/
import java.util.Stack;
import java.util.Scanner;
import java.io.File;
import java.io.FileReader;
import java.lang.Exception;
import java.util.LinkedList;
// This class will represent information about a part in the board and will be used by the
// algorithim to determine what to do next.
class Node {
private static Stack<Node> pathLocation = new Stack<>(); // Create a stack that will hold nodes for the algorithm
// to traverse the area.
private static LinkedList<int[]> checkedLocations = new LinkedList<int[]>();
private static int totalMoves = 0;
private int rowNumber, columnNumber;
private boolean checked;
public Node() { // Constructor for a default node.
}
// Gets the current node in the stack.
public Node getLocaiton() {
return pathLocation.peek();
}
// Removes a node from the stack.
public void removeLocation() {
pathLocation.pop();
}
// Adds a new node to the stack.
public void newLocation(Node nextPath) {
pathLocation.push(nextPath);
}
public Stack<Node> getStack() {
return pathLocation;
}
public int getRowLocation() {
return rowNumber;
}
public int getColumnLocation() {
return columnNumber;
}
public void setRowLocation(int inputRow) {
rowNumber = inputRow;
}
public void setColumnLocation(int inputColumn) {
columnNumber = inputColumn;
}
public void setChecked(boolean input) {
checked = input;
}
public boolean getChecked() {
return checked;
}
public int getTotalMoves() {
return totalMoves;
}
public void setTotalMoves(int input) {
totalMoves = input;
}
public boolean getChecked(int inputColumn, int inputRow) {
for (int[] i : checkedLocations) {
if (inputColumn == i[0] && inputRow == i[1]) {
return true;
}
}
return false;
}
public boolean addChecked(int inputColumn, int inputRow) {
this.setColumnLocation(inputColumn);
this.setRowLocation(inputRow);
for (int[] i : checkedLocations) {
if (this.getColumnLocation() == i[0] && this.getRowLocation() == i[1]) {
--totalMoves;
this.checked = true;
return this.checked;
}
}
int[] temp = { this.getColumnLocation(), this.getRowLocation() };
checkedLocations.push(temp);
this.checked = false;
++totalMoves;
return this.checked;
}
}
class Board {
private int size; // This will determine the size of the board which is obtained from the
// BoardFile class.
private char[][] boardArea; // The current location on the board. This current program supports double
// array. Could later be upgraded to support more dimensions.
private int boardColumn;
private int boardRow;
Board(BoardFile inputBoard) throws Exception { // This constructor could throw and exception.
Scanner boardRead = inputBoard.processedBoard(); // Obtained the scanner from the boardFile class.
String temp; // Strings that will be processed and saved by the scanner.
while (boardRead.hasNext()) { // Processes infromation from the board as long as there is information to read.
temp = boardRead.nextLine(); // Sets a temp string equal to what was next in the file.
int tempSize; // Remembers the size of the temp string.
size = temp.length(); // Sets the total size of game area.
boardColumn = size;
boardArea = new char[size][size];
int j = 0;
boolean startFound = false, endFound = false; // Makes sure there is a finish and a start.
while (temp.length() == size) {
for (int i = 0; i < temp.length(); ++i) { // This loop will construct the game board and
// and makes sure everything is correct.
if (temp.charAt(i) == 'X' || temp.charAt(i) == 'O' || temp.charAt(i) == 'F' || temp.charAt(i) == 'S') {
boardArea[i][j] = temp.charAt(i);
// The following if statements check to make sure there is only one instance of
// finish and start.
if (temp.charAt(i) == 'F' && !endFound) {
endFound = true;
}
else if (temp.charAt(i) == 'F' && endFound) {
throw new Exception("The finish was already found. Please check and try again.");
}
else if (temp.charAt(i) == 'S' && !startFound) {
startFound = true;
}
else if (temp.charAt(i) == 'S' && startFound) {
throw new Exception("The start was already found. Please check and try again.");
}
}
else {
// throws an exception in case one of the characters was not excpected.
throw new Exception("There was a incorrect character within the board. Please check and try again.");
}
}
if (boardRead.hasNext()) {
tempSize = temp.length(); // Assign the previous line size.
temp = boardRead.nextLine(); // Assign the next line.
if (tempSize != temp.length()) { // Check to make sure both lines are the same size.
throw new Exception("The size of the board is not correct. Please check and try again.");
}
}
else {
break;
}
++j; // Increment the row.
if (j > size - 1) { // Makes sure the area in the map is correct.
throw new Exception("The area in the map is not the same. Please check and try again.");
}
boardRow = j; // Sets the row number.
}
if (j != size - 1) {
throw new Exception("The area in the map is not the same. Please check and try again.");
}
if (!endFound) {
throw new Exception("The end was not found. Please check and try again.");
}
if (!startFound) {
throw new Exception("The start was not found. Please check and try again.");
}
}
}
public char[][] getBoardArea() { // Returns the array.
return boardArea;
}
public char getBoardLocation(int inputColumn, int inputRow) { // Gets a character a certain location
return boardArea[inputColumn][inputRow]; // within the array.
}
public int getBoardColumn() { // Gets the column total.
return boardColumn - 1;
}
public int getBoardRow() { // Gets the row total.
return boardRow;
}
}
// The class used to read a file.
class BoardFile {
private File file;
private FileReader createdBoard;
private Scanner readBoard;
BoardFile(String fileName) throws Exception { // Creates a file reader object.
file = new File(fileName);
if (!file.exists()) { // Makes sure the file is found.
throw new Exception("The file could not be found.");
}
createdBoard = new FileReader(file); // Creates the file reader.
readBoard = new Scanner(createdBoard); // Creates a new scanner object to read the board.
}
public Scanner processedBoard() { // Gets the scanner object from the read board.
return this.readBoard;
}
}
// This class is the actual searching and will be used to traverse the map.
public class PathSearch {
private Node node = new Node(); // Creates the node object to traverse the map area.
private Board board; // Creates the map.
private Integer[] saveLocation = new Integer[2]; // Create an array that saves a certain location.
PathSearch() throws Exception { // Accepts nothing but asks for a string that searchs for a file.
Scanner input = new Scanner(System.in);
String userFile;
System.out.println("Please enter the name of the file.");
userFile = input.nextLine();
input.close();
board = new Board(new BoardFile(userFile)); // This creates the board from a file that was input.
for (int i = 0; i < board.getBoardColumn(); ++i) { // Searches the board for the starting point.
for (int j = 0; j < board.getBoardRow(); ++j) {
if (board.getBoardLocation(i, j) == 'S') {
node.newLocation(new Node()); // Creates a new element in the stack.
saveLocation[0] = i; // Saves the column in which the node was found.
saveLocation[1] = j; // Saves the row in which the node was found.
System.out.println("Start found at " + (saveLocation[0]) + " " + (saveLocation[1]));
break; // Exits the loop since the information that was needed was processed.
}
}
}
if (saveLocation == null) {
throw new Exception("No starting point was found. Please check and try again.");
}
checkPath(saveLocation[0], saveLocation[1]);
}
// This method accepts two seperate inputs because it needs to remember if it
// checked the position it is currently at.
public Stack<Node> checkPath(int inputColumn, int inputRow) throws Exception {
node.addChecked(inputColumn, inputRow); // Get the current node and check if has been used already.
if (node.getChecked() && !node.getStack().empty()) { // Sees if it was checked and if the stack is not empty.
node.removeLocation(); // Removes the current node from the stack.
checkPath(node.getLocaiton()); // Uses the previous node to keep checking,
}
else {
Node tempNode = new Node(); // Creates a new temp node.
tempNode.setColumnLocation(inputColumn);
tempNode.setRowLocation(inputRow);
node.newLocation(tempNode); // Adds the temp node into the stack.
checkPath(node.getLocaiton()); // Starts checking at the new location.
}
return null; // Path was not found.
}
// This is a overloaded version of checkPath that accepts the current node
// and begins looking at the current node.
public Stack<Node> checkPath(Node node) throws Exception {
int inputColumn = node.getLocaiton().getColumnLocation();
int inputRow = node.getLocaiton().getRowLocation();
if (board.getBoardLocation(inputColumn, inputRow) == 'F') {
System.out.println("The end was found at " + node.getLocaiton().getColumnLocation()
+ " " + node.getLocaiton().getRowLocation());
System.out.println("Here is the path.");
while (!node.getStack().empty()) { // While the stack has information.
System.out.println(node.getLocaiton().getColumnLocation() + " " + node.getLocaiton().getRowLocation());
node.removeLocation(); // Remove the node to process the next.
}
System.out.println("The total moves were " + node.getTotalMoves());
return node.getStack();
}
// All statements to determine where to move next within the board.
if (inputColumn < board.getBoardColumn() && (board.getBoardLocation(inputColumn + 1, inputRow) == 'O'
|| board.getBoardLocation(inputColumn + 1, inputRow) == 'F')
&& !node.getChecked(inputColumn + 1, inputRow)) {
checkPath(inputColumn + 1, inputRow);
}
if (inputColumn > 0 && (board.getBoardLocation(inputColumn - 1, inputRow) == 'O'
|| board.getBoardLocation(inputColumn - 1, inputRow) == 'F')
&& !node.getChecked(inputColumn - 1, inputRow)) {
checkPath(inputColumn - 1, inputRow);
}
if (inputRow < board.getBoardRow() && (board.getBoardLocation(inputColumn, inputRow + 1) == 'O'
|| board.getBoardLocation(inputColumn, inputRow + 1) == 'F')
&& !node.getChecked(inputColumn, inputRow + 1)) {
checkPath(inputColumn, inputRow + 1);
}
if (inputRow > 0 && (board.getBoardLocation(inputColumn, inputRow - 1) == 'O'
|| board.getBoardLocation(inputColumn, inputRow - 1) == 'F')
&& !node.getChecked(inputColumn, inputRow - 1)) {
checkPath(inputColumn, inputRow - 1);
}
return null; // No path was found at that location.
}
}

Why is the int[] array I'm printing out being cut off?

I'm trying to print out an int[] array for this assignment I'm working on. My code is as follows:
import VacuumCleanerEnvironment.Constants;
import java.util.*;
/**
* Agent Class
* Student's Assignment
*/
public class Agent {
private String action = null;
public Agent() {
}
private boolean wallCheck(Set walls, int row, int col, int i){
int[] temp = {row, col};
if(i == 1){ // up
temp[0]--;
}else if(i == 2){ //right
temp[1]++;
}else if(i == 3){ // down
temp[0]++;
}else{ // left
temp[1]--;
}
return walls.contains(temp);
}
private void addWall(Set walls, int row, int col, String dir){
int[] temp = {row,col};
if(dir == "up"){
temp[0]--;
}else if(dir == "left"){
temp[1]--;
}else if(dir == "right"){
temp[1]++;
}else if(dir == "down"){
temp[0]++;
}
walls.add(temp);
}
/**
* can return:
* "up", "right", "down", "left", "suck dirt", "stay idle"
* #return String
*/
public String action(boolean dirty, boolean bump,int row, int col){
//System.out.println(Constants.SIZE);
//System.out.println(Constants.initialDirtProb);
//System.out.println(Constants.dirtyProb);
//System.out.println(Constants.dirtSensorFailProb);
//System.out.println(Constants.bumpSensorFailProb);
// System.out.println("\nbump:" + bump);
// System.out.println("dirty:" + dirty);
// System.out.println("row:" + row);
// System.out.println("col:" + col);
//int r = Constants.randomGen.getInt(4);
Set<int[]> walls = new HashSet<int[]>();
// int[] wallRoom = new int[2];
if (dirty)
{
action="suck dirt";
}
else
{
if(bump == true){
this.addWall(walls, row, col, action);
System.out.print("Walls:" + walls);
Iterator value = walls.iterator();
while(value.hasNext()){
System.out.print("," + (int[])value.next());
}
System.out.println();
}
Random r = new Random();
int i = r.nextInt(4);
while(this.wallCheck(walls, row, col, i)){
System.out.println("wallcheck: " + this.wallCheck(walls, row, col, i));
i = r.nextInt(4);
}
if(i == 1) {
action = "up";
}
else if(i == 2) {
action = "right";
}
else if(i == 3) {
action = "down";
}
else {
action = "left";
}
}
return action;
}
}
I am actually having 2 problems:1) The method wallCheck isn't running and I'm assuming it's because the int[] values are being saved as references and not values. How can I check if my HashSet contains a specific int[] value? (used to locate the walls on a map). 2) Why are my values being cut off when I print out my HashSet "walls". They are printing out like this:
Walls:[[I#1515e375],[I#1515e375
Walls:[[I#4abd1f59],[I#4abd1f59
Walls:[[I#e4612e6],[I#e4612e6
Walls:[[I#6936b791],[I#6936b791
Thanks in advance!
-------------------------------- EDIT -------------------------------
Ok guys I figured out what the problem was. Like Dave said it Java doesn't print out array's nicely, so I had to print it out myself. Also, I was declaring the HashSet INSIDE the action method, that's why only 1 value was being stored.

Homework help: Array being weird [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 4 years ago.
I'm working on a Binary Search Tree assignment, and I was testing what I thought was the finished product when I saw that when I added a number to the tree and then tried to check it's predecessor/successor (by putting it into an array using in order traverse and then checking the index before/after it) it just...didn't work. Any time I try to check the predecessor/successor of a value I just put in the middle of the tree, it wigs out with an ArrayIndexOutOfBoundsException. Important note is that simply printing out using inordertraverse (called printInOrder in the code) works perfectly.
Since printing the inorder traverse works, I can assume my tree isn't the problem. The only other thing is the array, right? Am I missing something obvious?
Here's the code!
public class BST implements BSTInterface
{
//Variables/Fields
private BNode root;
//Constructors
public BST(int data)
{
root = new BNode(data);
}
//Public Methods
public boolean add(int data)
{
if(!contains(data))
{
root = addEntry(root, data);
return true;
}
else
return false;
}
public boolean contains(int data)
{
return containsNode(root, data);
}
public boolean remove(int data)
{
if(contains(data))
{
root = deleteNode(root, data);
return true;
}
else
return false;
}
public int[] toArray()
{
int[] output = new int[root.numNodes()];
inorderTraverse(output, 0, root);
return output;
}
public void printInOrder()
{
printIn(root);
}
public void printPreOrder()
{
printPre(root);
}
public void printPostOrder()
{
printPost(root);
}
//Private methods/classes
private class BNode
{
private int data;
private BNode leftChild;
private BNode rightChild;
public BNode(int data)
{
this.data = data;
leftChild = null;
rightChild = null;
}
public int getData()
{
return data;
}
public void setData(int newData)
{
data = newData;
}
public BNode getLeftChild()
{
return leftChild;
}
public BNode getRightChild()
{
return rightChild;
}
public void setRightChild(BNode node)
{
rightChild = node;
}
public void setLeftChild(BNode node)
{
leftChild = node;
}
public int numNodes()
{
int leftNum = 0;
int rightNum = 0;
if(leftChild != null)
leftNum = leftChild.numNodes();
if(rightChild != null)
rightNum = rightChild.numNodes();
return 1+leftNum+rightNum;
}
}
private BNode addEntry(BNode current, int data)
{
if(current == null)
return new BNode(data);
if(data < current.getData())
current.setLeftChild(addEntry(current.getLeftChild(), data));
else if(data > current.getData())
current.setRightChild(addEntry(current.getRightChild(), data));
return current;
}
private boolean containsNode(BNode current, int entry)
{
if(current == null)
return false;
if(entry == current.getData())
return true;
if(entry < current.getData())
return containsNode(current.getLeftChild(), entry);
else
return containsNode(current.getRightChild(), entry);
}
private BNode deleteNode(BNode current, int data)
{
if(current == null)
return null;
if(data == current.getData())
{
if(current.getLeftChild() == null && current.getRightChild() == null) //No children
return null;
if(current.getRightChild() == null) //Only right child
return current.getLeftChild();
if(current.getLeftChild() == null) //Only left child
return current.getRightChild();
int smallestChild = findSmallest(current.getRightChild());
current.setData(smallestChild);
current.setRightChild(deleteNode(current.getRightChild(), smallestChild));
return current;
}
if(data < current.getData())
{
current.setLeftChild(deleteNode(current.getLeftChild(), data));
return current;
}
else
current.setRightChild(deleteNode(current.getRightChild(), data));
return current;
}
private int findSmallest(BNode root)
{
return root.getLeftChild() == null ? root.getData() : findSmallest(root.getLeftChild());
}
private void inorderTraverse(int[] array, int count, BNode node)
{
if(node != null)
{
inorderTraverse(array, count, node.getLeftChild());
array[count] = node.getData();
count++;
inorderTraverse(array, count, node.getRightChild());
}
}
private void printIn(BNode node)
{
if(node != null)
{
printIn(node.getLeftChild());
System.out.print(node.getData() + " ");
printIn(node.getRightChild());
}
}
private void printPre(BNode node)
{
if(node != null)
{
System.out.print(node.getData() + " ");
printPre(node.getLeftChild());
printPre(node.getRightChild());
}
}
private void printPost(BNode node)
{
if(node != null)
{
printPost(node.getLeftChild());
printPost(node.getRightChild());
System.out.print(node.getData() + " ");
}
}
}
along with the driver program:
import java.util.Scanner;
public class BSTDemoReel
{
public static void main(String[] args)
{
System.out.println("This search tree only handles integers! Thanks in advance!\n\n");
Scanner keyboard = new Scanner(System.in);
//Variables
String input;
String choice = "";
int num;
int index;
boolean found;
//Starting
System.out.println("Please enter the initial sequence of values:\n");
input = keyboard.nextLine();
String[] splitInput = input.split(" ");
int[] intInputArray = new int[splitInput.length];
for(int count = 0; count < splitInput.length; count++)
{
intInputArray[count] = Integer.parseInt(splitInput[count]);
}
BST searchTree = new BST(intInputArray[0]);
for(int count = 1; count < intInputArray.length; count++)
{
searchTree.add(intInputArray[count]);
}
System.out.print("Pre-order: ");
searchTree.printPreOrder();
System.out.println();
System.out.print("In-order: ");
searchTree.printInOrder();
System.out.println();
System.out.print("Post-order: ");
searchTree.printPostOrder();
System.out.println();
//Menu
while(!choice.equals("E"))
{
System.out.print("Command? ");
choice = keyboard.next();
choice = choice.toUpperCase();
switch(choice)
{
case "I": num = keyboard.nextInt();
if(searchTree.contains(num))
System.out.println(num + " already exists. Please try again.");
else
{
searchTree.add(num);
System.out.print("In-order: ");
searchTree.printInOrder();
System.out.println();
}
break;
case "D": num = keyboard.nextInt();
if(!searchTree.contains(num))
System.out.println(num + " does not exist. Please try again.");
else
{
searchTree.remove(num);
System.out.print("In-order: ");
searchTree.printInOrder();
System.out.println();
}
break;
case "P": num = keyboard.nextInt();
if(searchTree.contains(num))
{
int[] array = searchTree.toArray();
index = 0;
found = false;
while(!found)
{
if(num == array[index])
found = true;
else
index++;
}
if(index != 0)
System.out.println(array[index-1]);
else
System.out.println("That was the first one!");
}
else
System.out.println(num + " does not exist! Please try again!");
break;
case "S": num = keyboard.nextInt();
if(searchTree.contains(num))
{
int[] array = searchTree.toArray();
index = 0;
found = false;
while(!found)
{
if(num == array[index])
found = true;
else
index++;
}
if(index != array.length-1)
System.out.println(array[index+1]);
else
System.out.println("That was the last one!");
}
else
System.out.println(num + " does not exist! Please try again!");
break;
case "E": System.out.println("Was a tricky one! Thanks for playing ;P");
break;
case "H": System.out.println("I Insert a value\n" +
"D Delete a value\n" +
"P Find predecessor\n" +
"S Find successor\n" +
"E Exit the program\n" +
"H Display this message");
break;
default: System.out.println("Invalid command. Type H for help.");
break;
}
}
keyboard.close();
}
}
If you add a couple of lines of code to print out the array returned by searchTree.toArray() before you enter the while loop that examines the array to find the value specified with the P or S commands then you'll see the cause of the problem. The array is not filled in correctly. The desired value might not be present in the array, which means that found will never become True and the while loop will continue to increment index until it exceeds the size of the array and triggers the exception that you're seeing.
Since the array is supposed to be populated by inorderTraverse(), this suggests that that function isn't doing its job correctly. The reason why it is misbehaving is that its inner recursive calls to itself do not modify the value of the count variable for the caller. count is a simple int variable, therefore the count++ statement inside the recursive call does not affect the value of count in the calling function.
Your best options are either to change inorderTraverse() so that it returns the index of the array element that should be filled in next, or change count to be an Object that contains an int member whose updated value will be visible to the caller after it has been incremented inside the recursively called function.
Since this is an assignment I'm not going to show a corrected version of the program. The change is small, so given what you've done so far I expect that you won't have much trouble making it work.
BTW, your program is missing implementations of printIn(), printPre() and printPost(). They're not hard to write, but it's an extra hurdle for anyone who might have been interested in helping you tackle the problem. That might be at least part of the reason why no-one else has offered an answer yet. The easier you make it for people to reproduce the problem, the more likely it is that you'll get answers.

Connecting a wrapper class to another class

So I have this wrapper program that enables me to return two quantities from a method.
** Wrapper Class**
public class Words
{
private String leftWords;
private String rightWords;
public Words(String leftWords, String rightWords) {
this.leftWords = leftWords;
this.rightWords = rightWords;
}
public String getLeftWords() {
return leftWords;
}
public String getRightWords() {
return rightWords;
}
#Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((leftWords == null) ? 0 : leftWords.hashCode());
result = prime * result
+ ((rightWords == null) ? 0 : rightWords.hashCode());
return result;
}
#Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Words other = (Words) obj;
if (leftWords == null)
{
if (other.leftWords != null)
return false;
}
else if (!leftWords.equals(other.leftWords))
return false;
if (rightWords == null)
{
if (other.rightWords != null)
return false;
}
else if (!rightWords.equals(other.rightWords))
return false;
return true;
}
}
The method I want to tie this with is :
private static Map <Set<String>,Set<Words>> getLeftRightWords(LinkedHashMap<Set<String>,Set<Integer>> nnpIndexTokens, NLChunk chunk) throws FileNotFoundException
{
// Map <Set<String>,Set<Integer>> nnpMap = new LinkedHashMap<Set<String>, Set<Integer>>();
Map <Set<String>,Set<Words>> contextMap = new LinkedHashMap<Set<String>, Set<Words>>();
Set<Words> leftRightWords = new HashSet<Words>();
//for(NLChunk chunk : sentence.getChunks()){
if(chunk.getStrPostags().contains("NNP")){
String leftWords = "";
String rightWords = "";
int chunkStartIndex = chunk.getStartIndex();
int chunkEndIndex = chunk.getEndIndex();
//nnpMap = getNNPs(chunk);
String previous = null;
int previousNnpEndIndex = 0;
int previousNnpStartIndex = 0;
for (Map.Entry<Set<String>, Set<Integer>> entry : nnpIndexTokens.entrySet()){
for (Iterator<String> i = entry.getKey().iterator(); i.hasNext();){
Set<Integer> entryIndex = null;
int nnpStartIndex = 0;
int nnpEndIndex = 0;
String currentElement = i.next();
//Deriving values for beginning and ending of chunk
//and beginning and ending of NNP
if (!(entry.getValue().isEmpty())){
if (currentElement.trim().split(" ").length > 1){
entryIndex = entry.getValue();
nnpStartIndex = entryIndex.iterator().next();
nnpEndIndex = getLastElement(entryIndex);
}
else {
entryIndex = entry.getValue();
nnpStartIndex = entryIndex.iterator().next();
nnpEndIndex = nnpStartIndex;
}
}
if(!(chunkStartIndex<=nnpStartIndex && chunkEndIndex>=nnpEndIndex)){
continue;
}
//Extracting LEFT WORDS of the NNP
//1)If another NNP is present in left words, left words of current NNP start from end index of previous NNP
if (previous != null && chunk.toString().substring(chunkStartIndex, nnpStartIndex).contains(previous)){
int leftWordsEndIndex = nnpStartIndex;
int leftWordsStartIndex = previousNnpEndIndex;
for (NLWord nlword : chunk.getTokens())
{
if(nlword.getIndex()>=leftWordsStartIndex
&& nlword.getIndex()<leftWordsEndIndex )
leftWords+=nlword.getToken() +" ";
}
System.out.println("LEFT WORDS:" + leftWords+ "OF:"+ currentElement);
}
//2) If no left words are present
if (chunkStartIndex == nnpStartIndex){
System.out.println("NO LEFT WORDS");
}
//3) Normal case where left words consist of all the words left of the NNP starting from the beginning of the chunk
else {
for (NLWord nlword : chunk.getTokens())
{
if(nlword.getIndex()>=chunkStartIndex
&& nlword.getIndex()<nnpStartIndex )
leftWords+=nlword.getToken() +" ";
}
System.out.println("LEFT WORDS:" + leftWords+ "OF:"+ currentElement);
}
//Extracting RIGHT WORDS of NNP
if (entry.getKey().iterator().hasNext()){// entry.getKey().iterator().hasNext()){
String nextElement = entry.getKey().iterator().next();
//1)If another NNP is present in right words, right words of current NNP start from end index of current NNP to beginning of next NNP
if (nextElement !=null && nextElement != currentElement && chunk.toString().substring(entry.getValue().iterator().next(), chunkEndIndex).contains(nextElement)){
int rightWordsStartIndex = entryIndex.iterator().next();
int rightWordsEndIndex = entry.getValue().iterator().next();
//String rightWord="";
for (NLWord nlword : chunk.getTokens())
{
if(nlword.getIndex()>=rightWordsStartIndex
&& nlword.getIndex()<rightWordsEndIndex )
rightWords+=nlword.getToken() +" ";
}
System.out.println("LEFT WORDS:" + leftWords+ "OF:"+ currentElement);
}
}
//2) If no right words exist
if(nnpEndIndex == chunkEndIndex){
System.out.println("NO RIGHT WORDS");
//continue;
}
//3) Normal case where right words consist of all the words right of the NNP starting from the end of the NNP till the end of the chunk
else {
for (NLWord nlword : chunk.getTokens())
{
if(nlword.getIndex()>=nnpEndIndex+1
&& nlword.getIndex()<=chunkEndIndex )
rightWords+=nlword.getToken() +" ";
}
System.out.println("RIGHT WORDS:" + rightWords+ "OF:"+ currentElement);
}
if (previous == null){
previous = currentElement;
previousNnpStartIndex = nnpStartIndex;
previousNnpEndIndex = nnpEndIndex;
}
Words contextWords = new Words(leftWords.toString(), rightWords.toString());
leftRightWords.add(contextWords);
}
contextMap.put(entry.getKey(), leftRightWords);
}//nnps set
}
System.out.println(contextMap);
return contextMap;
}
As you can see what I am trying to do in this method is taking a proper noun and extracting the left and right words of that proper noun.E.g for a chunk "fellow Rhode Island solution provider" my output is:
LEFT WORDS:fellow OF:Rhode Island
RIGHT WORDS:solution provider OF:Rhode Island
Now I want to put these in a map where Rhode Island is the key and the values for this are solution provider and fellow.
When I try to print this map the output get is:
{[Rhode Island ]=[com.gyan.siapp.nlp.test.Words#681330f0]}
How do i get the right output?
I don't know if it is the only issue but your class Words does not override
toString() method.
Not sure about your Java skill level. So sorry if im posting what you are familiar to.
System.out.println(...) calls toString() method to get message for the object.
By overriding default with your own implementation
#Override
public String toString(){
return "leftWords: "+leftWords+", rightWords: "+rightWords;
}
You change com.gyan.siapp.nlp.test.Words#681330f0 to your own output.

What's causing my stackoverflowerror in my maze solver?

I have to solve a maze using recursion and everything was going fine until I ran the program and ran into a stackoverflowerror. I've read a couple other questions on the site and they all say it's because of infinite recursion however none of their issues seem to be the exact same as mine.
my netID_maze.java file
import java.util.Random;
public class netID_Maze
{
int exitRow,
entranceRow;
char[][] map = null;
// Method Name : Maze (Constructor)
// Parameters : None
// Partners : None
// Description : No Parameter Constructor for the maze
public netID_Maze()
{
// omitted code generating a random maze
setEntranceRow(rnger.nextInt(row - 2) + 1);
setExitRow(rnger.nextInt(row - 2) + 1);
map[getEntranceRow()][0] = '.';
map[getExitRow()][column - 1] = '.';
} // end netID_Maze (without parameters)
// Method Name : Maze (Constructor)
// Parameters : exitTemp (int), entranceTemp(int), mapTemp (char[][])
// Partners : None
// Description : Parameter Constructor for the maze
public netID_Maze(char[][] mapTemp, int exitTemp, int entranceTemp)
{
map = mapTemp;
exitRow = exitTemp;
entranceRow = entranceTemp;
} // end netID_Maze (with parameters)
// Method Name : getCell
// Parameters : row (int), column (int), character in cell (character)
// Partners : None
// Returns : The character in the cell that's being called (character)
// Description : Returns the character of the cell that's being called
public char getCell(int r, int c)
{
return map[r][c];
} // end getCell()
// Method Name : setCell
// Parameters : row (int), column (int), character in cell (character)
// Partners : None
// Returns : None
// Description : Changes the character of the cell that's being called
public void setCell(int r, int c, char val)
{
this.map[r][c] = val;
} // end setCell()
public int getEntranceRow ()
{
return entranceRow;
}
public int getExitRow()
{
return exitRow;
}
public void setEntranceRow(int entranceTemp)
{
entranceRow = entranceTemp;
}
public void setExitRow(int exitTemp)
{
exitRow = exitTemp;
}
public int getRows()
{
return map.length;
}
public int getColumns()
{
return map[1].length;
}
public boolean isExit(int r, int c)
{
boolean isExit = false;
if (getExitRow() == r && map[1].length - 1 == c)
{
isExit = true;
}
return isExit;
}
public boolean isEntrance(int r, int c)
{
boolean isEntrance = false;
if (getEntranceRow() == r && 0 == c)
{
isEntrance = true;
}
return isEntrance;
}
public boolean isOpen(int r, int c)
{
boolean isOpen = true;
if (r < 0 || c < 0 || r >= getRows() || c >= getColumns())
{
isOpen = false;
}
else if (map[r][c] == '.')
{
isOpen = false;
}
return isOpen;
}
}
and my netID_MazeSolver.java file
public class netID_MazeSolver {
int steps = 0;
netID_Maze maze = new netID_Maze();
public netID_MazeSolver(netID_Maze mazeTemp)
{
setSteps(0);
maze = mazeTemp;
}
public boolean solveMaze(int r, int c)
{
//Finding whether Current Cell is outside the maze
if (r < 0 || c < 0 || r >= maze.getRows() || c >= maze.getColumns())
{
return false;
}
//Finding whether the current cell is the exit
if (maze.isExit(r,c) == true)
{
return true;
}
//Finding whether current cell is NOT open
if (maze.isOpen(r,c) == false)
{
return false;
}
//Setting current cell as part of the solution path
//Finding out whether solve maze(cell below current) == true
if (solveMaze(r - 1,c) == true)
{
return true;
}
//Finding out whether solve maze(cell to the right of current) == true
if (solveMaze(r,c + 1) == true)
{
return true;
}
//Finding out whether solve maze(cell to the left of current) == true
if (solveMaze(r,c - 1) == true)
{
return true;
}
//Finding out whether solve maze(cell above current) == true
if (solveMaze(r + 1,c) == true)
{
return true;
}
//setting current cell to NOT part of the solution path
return false;
}
public void setSteps(int stepsTemp)
{
steps = stepsTemp;
}
public int getSteps()
{
return steps;
}
}
The actual error just keeps repeating:
at netID_MazeSolver.solveMaze(netID_MazeSolver.java:53)
at netID_MazeSolver.solveMaze(netID_MazeSolver.java:71)
The basic mistake you made, was that you don't set any flags for visited cells. Due to this, your algorithm can visit the same cell again and again. If your generated maze contains any cycles, you're pretty likely to end up in an endlessloop causing a stackoverflow. And btw, you don't need, to write if(maze.isOpen(r , c) == true). if(maze.isOpen(r , c)) gives the same result with less code.

Categories