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.
}
}
Related
I have the following code where I have implemented a circular array. The problem comes when I try to display it. The display method works well until the array gets full and last goes back to 0. Therefore last and first are both 0 and the for loop doesn't execute.
public class PassengerQueue
{
private Passenger[] queueArray = new Passenger[TrainStation.WAITING_ROOM_CAPACITY];
private int first = 0;
private int last = 0;
private int maxStayInQueue = 0; //number of seconds that the passenger who stayed longest in the queue
private int maxLength = 0; //the maximum legth that was reached by the queue
private int currentSize = 0;
public void add(Passenger next)
{
//if the queue is not full - check for the circular queue
if (isFull()){
System.out.println("The queue is full");
}
else
{
queueArray[last] = next;
last = (last + 1) % queueArray.length;
currentSize++;
maxLength++;
}
}
public Passenger remove()
{
Passenger removedPassenger = null;
//if the queue array is not empty
//remove passenger
if (isEmpty())
{
System.out.println("The queue is empty");
}
else
{
removedPassenger = queueArray[first];
queueArray[first] = null;
first = (first + 1) % queueArray.length;
currentSize--;
}
return removedPassenger;
}
public Boolean isEmpty()
{
return (currentSize == 0);
}
public Boolean isFull()
{
return (currentSize == queueArray.length);
}
public void display()
{
if (isEmpty())
{
System.out.println("The queue is empty");
}
else
{
for(int i = first; i < last; i++)
{
queueArray[i].display();
}
}
}
Any help would be appreciated! Thank You
You can change the loop so it iterates from 0 to size. This also fixes the problem where last is less than first because items have been removed.
for(int i = 0; i < currentSize; i++)
{
queueArray[(first + i) % queueArray.length].display();
}
Just use the properties on the array itself to display:
public void display()
{
if (isEmpty())
{
System.out.println("The queue is empty");
}
else
{
for(int i = 0; i < queueArray.length; i++)
{
queueArray[i].display();
}
}
}
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.
Write a method to find the position of a given element in a stack counting from the top of the stack. More precisely,
the method should return 0 if the element occurs on the top, 1 if there is another element on top of it, and so on. If
the element occurs several times, the topmost position should be returned. If the element doesn’t occur at all, -1
must be returned.
You are asked to write this method in two different ways; one way is to implement it internally inside the
ArrayStack class and the other way is to implement it externally in a separate class. Important: At the end
the stack should be returned to the original state (i.e. no elements should be removed and the order of the elements
should not change).
This is the externall class
public class Stack{
public static int searchstack(ArrayStack z, int n) {
ArrayStack temp = new ArrayStack(z.size());
int c = 0;
boolean flag = false;
while (!z.isEmpty()) {
if (z.top() == n) {
flag = true;
return c;
}
if (z.top() != n) {
temp.push(z.pop());
c++;
flag = false;
}
}
if (flag == false) {
c = -1;
}
while (!temp.isEmpty() && !z.isFull()) {
z.push(temp.pop());
}
return c;
}
public static void main(String[] args) {
ArrayStack z = new ArrayStack(4);
z.push(3); // first element
z.push(7);// 2nd
z.push(8);// 3rd
z.push(1);// 4th
z.printStack();
int n = 3;
System.out.println("Searching externally for" + " " + n + " " + searchstack(z, n));
System.out.println("Searching internally for" +" "+n+" "+ z.searchfor(n)+" "); //THE ERROR IS HERE
}
}
And this is the ArrayClass
public class ArrayStack {
private int[] theStack;
private int maxSize;
private int top;
public ArrayStack(int s) {
maxSize = s;
theStack = new int[maxSize];
top = -1;
}
public void push(int elem) {
top++;
theStack[top] = elem;
}
public int pop() {
int result = theStack[top];
top--;
return result;
}
public int top() {
return theStack[top];
}
public boolean isFull() {
return (top == (maxSize - 1));
}
public boolean isEmpty() {
return (top == -1);
}
public int size() {
return (top + 1);
}
//HERE IS THE METHOD I IMPLEMENTED INTERNALLY AND CALL IT AT THE STACK CLASS
public int searchfor(int n) {
for (int i = top; i >= 0; i--) {
if (theStack[top] == n) {
return i;
}
}
return -1;
}
public void printStack() {
if (top == -1)
System.out.println("Stack is empty!!\n");
else {
System.out.println(theStack[top] + " <- top");
for (int i = top - 1; i >= 0; i--)
System.out.println(theStack[i]);
System.out.println();
}
}
}
The error appearing at the Stack class is at the last line of calling the searchfor method implemented in the Arraystack class , error says that there is no method implemented in Arraystack with the name searchfor (); thiugh I did implement it .whatseems to be the problem ?
You have a bug in your searchStack() implementation. You are losing elements if you find the one you are looking for and it isn't the topmost one.
How to fix your searchStack() method:
keep popping z until you have an empty ArrayStack. While doing so, add the value to a queue.
create valIndex and assign it -1.
Then go through the queue and remove the items from it and adding them to z. While doing so, check for the last occurence of the desired value and save it in valIndex.
if valIndex equals -1 return it. Else, use following equation to convert it to correct index and return:
valIndex = (z.size - 1) - valIndex
I am having some trouble creating a linked list in Java. All of the guides I am following give examples using some kind of variable of type String, but the list I must create needs a type int. Using the type int will produce an error message when I try to call something like position.link because it says it cannot convert an int to a string.
For clarity, the main program should have Scanner ask for the int, and use that int to create a loop that creates each node. I have messed around with iterators and with just simple singular linked lists but I am not getting anywhere.
import java.util.NoSuchElementException;
public class SuitorLinkedList<Integer>
{
private class SuitorListNode
{
private int suitor;
private SuitorListNode link;
public SuitorListNode()
{
suitor = 0;
link = null;
}
public SuitorListNode(int newSuitor, SuitorListNode linkValue)
{
suitor = newSuitor;
link = linkValue;
}
} // End of SuitorListNode inner class
public class SuitorListIterator
{
public SuitorListNode position;
private SuitorListNode previous; // previous value of position
public SuitorListIterator()
{
position = head; // variable head of outer class
previous = null;
}
public void restart()
{
position = head;
previous = null;
}
public String next()
{
if(!hasNext())
throw new NoSuchElementException();
String toReturn = position.suitor;
previous = position;
position = position.link;
return toReturn;
}
public boolean hasNext()
{
return (position != null); // Throws IllegalStateExpression if false
} // Returns next value to be returned by next()
public String peak()
{
if(!hasNext())
throw new IllegalStateException();
return position.suitor;
}
public void addHere(int newData)
{
if(position == null && previous != null) // At end of list, add to end
previous.link = new SuitorListNode(newData, null);
else if(position == null || previous == null) // List empty or position is head node
head = new SuitorListNode(newData, head);
else // previous and position are consecutive nodes
{
SuitorListNode temp = new SuitorListNode(newData, position);
previous.link = temp;
previous = temp;
}
}
public void delete()
{
if(position == null)
throw new IllegalStateException();
else if (previous == null) // remove node at head
{
head = head.link;
position = head;
}
else // previous and position are consecutive nodes
{
previous.link = position.link;
position = position.link;
}
}
private SuitorListNode head;
}
public SuitorListIterator iterator()
{
return new SuitorListIterator();
}
}
I get this error every time I try, I've tried searching it up and using the toString() to help but it won't work:
SuitorLinkedList.java:60: error: incompatible types: int cannot be converted to String
return position.suitor;
^
I have tried creating the regular linked list and got this far:
public class SuitorList
{
public class SuitorNode
{
public int suitor;
public SuitorNode link;
public SuitorNode()
{
suitor = 0;
link = null;
} // Initialize veriables
public SuitorNode(int newSuitor, SuitorNode linkValue)
{
suitor = newSuitor;
link = linkValue;
} // Assigns values sent in from main
} // End inner class
private SuitorNode head; // Variable head of type SuitorNode (callback to Node program)
// Allows head to point to a node
public SuitorList()
{
head = null;
} // Initialize variables
// Memory space called head filled with null
public void addToStart(int suitorNum)
{
head = new SuitorNode(suitorNum, head);
}
// Creates node with head pointing to it at start of list
// head will have a definition as an object with a suitor and link = head
// If head = null, then link = null
// head is repositioned to point to node
public int size() // Reads size of list
{
int count = 0;
SuitorNode position = head; // Variable position of type SuitorNode will equal value at head; position points where head is pointing
while(position != null) // While list is not empty/ended
{
count++; // increase number of entries detected
position = position.link; // getLink will make position = link, leading to next entry in list
}
return count; // Display size.
}
public void outputList()
{
SuitorNode position = head; // Position points to same thing head points to
while(position != null) // While list is not empty/ended
{
System.out.println(position.suitor); // Print suitor
position = position.link; // Go to next entry
}
}
public void deleteNode(int count)
{
int moveCount = count - 1;
SuitorNode position = head;
while(head != link) // not winning
{
moveCount = count;
checkEnd(); // Checks for win before causing potential problem with 1 suitor left
checkTwoNumbersLeft(moveCount); // Takes care of movement when two nodes are left
checkEndNode(moveCount); // Checks when, for example, 2 nodes away
if(moveCount == count) // If checkEndNode and checkTwoNumbersLeft fail
{
position = position.link; // Move for first time
moveCount = moveCount - 1;
}
checkEnd();
checkEndNode2(moveCount); // When one movement is made already, deletes end node after
if(moveCount == moveCount - 1) // if checkEndNode2 fails
position = position.link.link; // 2nd deletion
count = moveCount;
}
isWinner();
} // End method deleteNode()
public void checkTwoNumbersLeft(int moveCount)
{
SuitorNode position;
if(position.link.link == null) // example: 1 5
{
createLoop();
position = position.link.link; // Deletes the 5
moveCount = moveCount - 2;
} // Used just in case only two numbers are present
} // End method checkTwoNumbersLeft()
public void checkEnd()
{
SuitorNode position;
if(position.link == null) // If at end of list
{
createLoop(); // creates a loop if the initial number has no next value
isWinner(); // If a 1 is used, the entire if statement will trigger
} // if true, head == link which will fall out of while in deleteNode()
} // End method checkEnd()
public void isWinner()
{
SuitorNode link;
SuitorNode position;
if(position == position.link)
{
head = link;
System.out.println("The winner is Suitor " + position + "!");
}
} // End method isWinner()
public void checkEndNode2(int moveCount)
{
SuitorNode position;
SuitorNode link;
if(position.link.link == null) // 1 movement
{
position.link = null;
createLoop();
isWinner();
moveCount = moveCount - 1;
}
} // End checkEndNode2()
public void checkEndNode(int moveCount)
{
SuitorNode position;
SuitorNode link;
if(position.link.link.link == null) // no movements
{
position = position.link;
position.link = null;
createLoop();
isWinner();
moveCount = moveCount - 2;
}
} // End checkEndNode()
public void createLoop()
{
SuitorNode position;
SuitorNode link;
if(link == null) // if at the end of the list
link = head; // Sets link to point to where head points, AKA beginning of list
} // End createLoop()
}
But when I do this, the variables link, position, and head always say they are not initialized unless I place them inside the method (which can mess up my code if I call the method while in the middle of the list).
My questions boil down to 1) How would I be able to convert the ints to strings in order to work with a linked list? and 2) Why are the variables in the program SuitorList requiring me to reinitialize them in every instance when I've tried placing them everywhere I could?
The issue is your peek function is defined as the wrong type
public String peak()
{
if(!hasNext())
throw new IllegalStateException();
return position.suitor;
}
It's defined as returning a String
Instead it should be defined as suitor's type, an int
public int peak()
{
if(!hasNext())
throw new IllegalStateException();
return position.suitor;
}
Same issue with public String next(), should instead be public int next()
The variable suitor is given the variable type of int. It is possible to turn it into a string. By converting it;
public String peak() { if(!hasNext()) throw new IllegalStateException(); return Integer.toString(position.suitor); }
This method should get rid of that error. Or using String.valueOf(position.suitor);.
I'm currently writing a parser for a language that I'm creating, which needs to check if the current part of the stream fits one of the items in the passed array. A short version of the code is:
public abstract class Parser {
private StringReader reader; //This is a BufferedReader with rollback
//A single string lookahead method
public boolean lookahead(String toMatch, boolean rollback) throws ParseException {
char c;
//Mark the current position in the stream, so we can come back to it if needed
MarkToken currentMark = reader.mark();
//Iterate through the toMatch and check if each character matches
for(int i = 0; i < toMatch.length(); ++i) {
c = reader.nextChar();
if(toMatch.charAt(i) != c) {
break;
}
}
//Get the current image
String got = reader.currentImage(currentMark);
//If we don't have a match, rollback if necessary and return false
if(!got.equals(toMatch)) {
if(rollback) {
reader.rollBack();
}
return false;
}
return true;
}
//The String[] lookahead method
public int lookahead(String[] toMatch, boolean rollback) throws ParseException {
if(toMatch.length == 1) {
//If there is only one element in toMatch, send it to a cheaper function
if(lookahead(toMatch[0]))
return 0;
else return 1;
} else {
int maxLength = toMatch[0].length();
//We use this variable to keep track of how many valid choices are left
int choicesLeft = toMatch.length;
int i, j;
char current;
//Mark the current position in the stream, so we can come back to it if needed
MarkToken mark = s().mark();
//Get the length of the longest string in toMatch
for(i = 1; i < toMatch.length; ++i) {
maxLength = Math.max(maxLength, toMatch[i].length());
}
//Go up to the length of the longest string
for(i = 0; i < maxLength; ++i) {
//Get the next character from the stream
current = reader.nextChar();
//If we've reached the end of the stream:
if(current == -1 || current == '\uffff') {
//Get back a character in the stream
reader.rollbackChar();
//And check to see if we have a match
return ArrayUtils.indexOf(toMatch, reader.currentImage(mark));
}
//Go through each item in toMatch
for(j = 0; j < toMatch.length; ++j) {
if(toMatch[j] != null) {
//Check to see if the character matches or not
if(toMatch[j].charAt(i) != current) {
//We null an item in toMatch if it doesn't apply any more
toMatch[j] = null;
--choicesLeft;
}
}
}
//If we only have one choice left, see if there is a match (will return -1 if not)
if(choicesLeft == 1) {
return ArrayUtils.indexOf(toMatch, reader.currentImage(mark));
}
}
//If there is no
if(rollback) {
reader.rollBackTo(mark);
}
}
return -1;
}
}
This function would be called to check if the stream contained certain symbols (. .* $# // " ' """ ''' etc.) and consume them greedily.
I would only be providing an array of maximum 10-15 items at once, so removing items from the array may not be the best optimisation.
Is there a more efficient way of doing this, certain methods or loops that I should be using?