Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Can anyone tell me where I did wrong? My Queue class is working like a Stack, not a Queue. If I enqueue 1, 2, and 3 (in that order) and then dequeue, it removes the 3, not the 1.
Thank you in advance!
I am not sure where I did wrong!
Here is my code:
import java.util.NoSuchElementException;
public class Queue implements QueueADT
{
private int front = 0;
private int back = 0;
private int [] a;
private int size = 10;
public Queue(){
a = new int [10];
}
public Queue(int size){
a = new int [size];
this.size = size;
}
//enqueue - adds an element to the back of the queue
public void enqueue(int element){
if(((back+1) - front) == -1 || ((back+1) - front) == (a.length - 1))
resizeArray();
if (back == a.length - 1)
back = 0;
a[back++] = element;
}
//dequeue - removes and returns the element from the
//front of the queue
public int dequeue(){
if(isEmpty())
throw new NoSuchElementException("Dequeue: Queue is empty");
if (front < back){
front ++;
return a[front-1];
}
else if (front > back){
front--;
return a[front++];
}
return 1;
}
//peek - returns but does not remove the element from
//the front of the queue
public int peek(){
if(isEmpty())
throw new NoSuchElementException("Peek: Queue is empty");
return a[front];
}
//isEmpty - determines if the queue is empty or not
public boolean isEmpty(){
return size() == 0;
}
private void resizeArray()
{
//double the size of the array
int[] newA = new int[a.length * 2];
int x = 0;
while(x < size - 1){
newA[x] = dequeue();
x++;
}
size = size *2;
front = 0;
back = x;
a = newA;
}
//size - returns the number of elements in our Queue
public int size(){
if (front > back ){
return size - (front - (back + 1));}
return back - front + 1;}
//toString - returns a String representation of our Queue
public String toString(){
if(isEmpty()) {
throw new NoSuchElementException("Queue is empty");
}
{
String s = "[ ";
//print queue
for(int i = 0; i < size(); i++)
s += a[i] + " ";
//print array
for(int j = size(); j < a.length; j++)
s += "* ";
s += "]";
return s;
}
}
//equals - determines if two queues are equivalent
//i.e. do they have the same elements in the same sequence
//ignoring the structure they are stored in
public boolean equals(Object otherQ){
if(otherQ == null)
return false;
else
{
//Figure out how many interfaces the other guy
//implements
int numIs = otherQ.getClass().getInterfaces().length;
boolean flag = false;
//look at all of the other guys interfaces
//and if he doesn't implement QueueADT, then
//he clearly isn't a Queue and we return false
for(int i = 0; i < numIs; i++)
{
if(this.getClass().getInterfaces()[0] ==
otherQ.getClass().getInterfaces()[i])
{
flag = true;
}
}
if(!flag)
return false;
else //we know that the other guy exists and
//we know that he implements QueueADT
{
QueueADT q = (QueueADT)otherQ;
if(this.size() != q.size())
return false;
else
{
boolean queuesEqual = true;
for(int i = 0; i < this.size(); i++)
{
int ourElement = this.dequeue();
int qElement = q.dequeue();
if(ourElement != qElement)
queuesEqual = false;
this.enqueue(ourElement);
q.enqueue(qElement);
}
//return our final answer
return queuesEqual;
}
}
}
}
public void showInnerWorkings(){
System.out.print("[");
for (int i = 0; i < this.a.length; i++)
System.out.print(this.a[i] +
(i != this.a.length - 1 ? ", " : ""));
System.out.println("]");
}
}
QueueADT interface:
public interface QueueADT
{
//enqueue - adds an element to the back of the queue
public void enqueue(int element);
//dequeue - removes and returns the element from the
//front of the queue
public int dequeue();
//peek - returns but does not remove the element from
//the front of the queue
public int peek();
//isEmpty - determines if the queue is empty or not
public boolean isEmpty();
//size - returns the number of elements in our Queue
public int size();
//toString - returns a String representation of our Queue
public String toString();
//equals - determines if two queues are equivalent
//i.e. do they have the same elements in the same sequence
//ignoring the structure they are stored in
public boolean equals(Object otherQ);
}
What do you really want? A Queue or a circular array ?
Circular array :
You should have a look there. As you can see, the simpliest (and the best) way is to extend the ArrayList class and override the get() method.
Queue :
Just use the java.util.Queue interface.
Related
I'm actually doing an easy CodinGame --> I have to find if an element exists in a list.
I've tested a first solution, it was working but it wasn't really optimized (according to the machine).
So I've tried another solution but :
When I test my code for this 2nd solution, it returns the right answers but when I'm submitting my code, it tells me that my solution is completely wrong (it doesn't work if the list is empty, and also if the list is huge, ...).
Please can you help me ?
Here is my first naive solution :
public static boolean check(int[] ints, int k) {
boolean res = false;
for(int i : ints){
if(i == k){
res = true;
break;
}
}
return res;
}
Here is the code of my 2nd solution that is supposed to be optimized:
static boolean exists(int [] ints, int k){
boolean res = false;
int first = 0;
int last = ints.length;
int mid = (first + last)/2;
while(first <= last){
if( ints[mid] < k){
first = mid +1;
}else if (ints[mid] == k){
res = true;
break;
}else{
last = mid -1;
}
mid = (first + last)/2;
}
if(first > last){
res = false;
}
return res;
}
Finally I've found the solution to my problem !!!!!
Here it is :
import java.util.Arrays;
class A{
static boolean exists(int[] ints, int k){
boolean res = false;
int index = Arrays.binarySearch(ints, k);
if (index<0){
res = false;
}else{
res = true;
}
return res;
}
}
I suppose you are trying to implement Binary search in the second solution.
If so, please check this answer. Your input array must be sorted in non-decreasing order, because Binary Search works only with sorted input data. For example, you can simply type Arrays.sort(arr); and then pass your array into exists() method. But the overall time&space complexities will be O(n log n).
Fixed some bugs in your implementation:
public static boolean exists(int[] ints, int k) {
int first = 0;
int last = ints.length - 1;
while (first <= last) {
int mid = first + (last - first) / 2; // to avoid integer overflow in extremely large arrays
if (ints[mid] < k) {
first = mid + 1;
} else if (ints[mid] == k) {
return true;
} else {
last = mid - 1;
}
}
return false;
}
I require an implementation of a Priority queue that allows decrease priority operation to allow for an efficient implementation for Prim's and Dijkstra's algorithm.
I've coded up a minHeap implementation using a HashMap to store the indices of elements in my heap.
The problem I'm working on requires the computation of the total weight of the minimum spanning tree obtained by using Prim's algorithm. While my implementation works for most test cases upto 200 nodes, I'm still getting the incorrect output for many larger test cases.
It is my understanding that such minheap based implementations of Priority queues using HashMaps are common, if I am wrong in my assumption, please provide the more suitable approach to this problem.
I've been trying to debug my code for 2 days now and it seems the only way to fix it would be to compare it with a correctly functioning implementation.
Therefore, can someone please share such a PriorityQueue implementation using HashMap in java.
Even though I've tried a lot of test cases and for all the ones I can trace on my own(upto 30 nodes) I've gotten correct answers so far, but if there are some specific boundary test cases that could help me identify the problem, that too will be great.
Here is my code, I understand debugging it will be time consuming for anyone else, but if there is something obvious I've missed and someone with more expertise can point out the mistake, that would be most appreciated.
import java.util.HashMap;
import java.util.NoSuchElementException;
public class Heap<Key extends Comparable<Key>> {
private Key[] heap;
private int maxN, n;
private HashMap<Key, Integer> map;
#SuppressWarnings("unchecked")
public Heap(int maxN) {
if(maxN < 0 ) throw new IllegalArgumentException();
this.maxN = maxN;
n = 0;
heap = (Key[]) new Comparable[maxN];
map = new HashMap<>(maxN);
}
boolean isEmpty() {
return n == 0;
}
boolean insert(Key e) {
if(n +1 > maxN) throw new IllegalArgumentException("maximum capacity reached " + maxN);
heap[n] = e;
map.put(e,n);
int i = n++;
while ( (i+1)/2 - 1 >= 0){
if ( e.compareTo(heap[(i+1)/2 - 1]) < 0 ) {
swap(i, (i+1)/2 - 1);
i = (i+1)/2 - 1;
}
else
break;
}
return true;
}
Key extractMin() {
if(n == 0) throw new NoSuchElementException("Priority queue underflow ");
Key min = heap[0];
swap(0, n-1);
map.remove(min);
n--;
int j = 0, s;
while(j <= (n/2)-1){
if(j == (n/2)-1 && n == (j+1)*2 )
s = (j+1)*2 - 1;
else
s = heap[(j+1)*2 - 1].compareTo(heap[(j+1)*2]) < 0 ? (j+1)*2 - 1 : (j+1)*2;
if(heap[j].compareTo(heap[s]) > 0 ){
swap(j, s);
j = s;
}
else break;
}
return min;
}
Key delete(Key e){
if(!map.containsKey(e)) throw new NoSuchElementException(e+"does not exist ");
int j = map.get(e), s;
Key del = e;
swap(j, n-1);
map.remove(e);
n--;
while( j <= n/2 - 1){
if(j == (n/2)-1 && n == (j+1)*2)
s = (j+1)*2 - 1;
else
s = heap[(j+1)*2 - 1].compareTo(heap[(j+1)*2]) < 0 ? (j+1)*2 - 1 : (j+1)*2;
if(heap[j].compareTo(heap[s]) > 0 ){
swap(j, s);
j = s;
}
else break;
}
return del;
}
boolean decreasePriority(Key e){
if(n == 0)
return insert(e);
if(map.containsKey(e))
delete(e);
return insert(e);
}
private void swap(int i, int j) {
Key t = heap[i];
heap[i] = heap[j];
heap[j] = t;
map.replace(heap[i], i);
map.replace(heap[j], j);
}
#Override
public String toString() {
String res = "[";
int i;
for (i = 0; i < n-1; i++){
res += heap[i] + ", ";
}
res += heap[i]+"]";
return res;
}
}
I think the problem is in your delete method. Your code does this:
swap item to be removed with the last item in the heap
reduce heap count
push the new item down the heap
You're making the assumption that heap[j] < heap[n-1]. That's not a valid assumption. Consider this heap:
1
6 2
7 8 3
If you delete the node with value 7, the value 3 replaces it:
1
6 2
3 8
You now have to move it up the tree to make a valid heap:
1
3 2
6 8
The key here is that if the item you're replacing is in a different subtree than the last item in the heap, it's possible that the replacement node will be smaller than the parent of the replaced node.
If you're removing an item from the middle of the heap, you swap the item with the last, then you have to check whether the replacement node moves up or down.
Something you should consider, though, is that to change an item's priority, you don't have to delete and re-add. All you have to do is change the priority and then adjust the item's position appropriately: move up or down to put it in its new position.
The delete method was incorrect, I was using the same procedure for arbitrary deletes as for extractMin, which did not take into account the fact that the element I replace the key to be deleted with could possibly go both up or down the heap. Using swim() and sink() methods I have rectified this error. Also to change priority deletion and insertion are not required, and a simple call to both swim and sink is sufficient.(only swim if only decreasing priority and only sink if only increasing).
import java.util.HashMap;
import java.util.NoSuchElementException;
public class Heap<Key extends Comparable<Key>> {
private Key[] heap;
private int maxN, n;
private HashMap<Key, Integer> map;
#SuppressWarnings("unchecked")
public Heap(int maxN) {
if(maxN < 0 ) throw new IllegalArgumentException();
this.maxN = maxN;
n = 0;
heap = (Key[]) new Comparable[maxN];
map = new HashMap<>(maxN);
}
boolean isEmpty() {
return n == 0;
}
boolean insert(Key e) {
if(n +1 > maxN) throw new IllegalArgumentException("maximum capacity reached " + maxN);
heap[n] = e;
map.put(e,n);
int i = n++;
swim(i);
return true;
}
Key extractMin() {
if(n == 0) throw new NoSuchElementException("Priority queue underflow ");
Key min = heap[0];
swap(0, n-1);
map.remove(min);
n--;
sink(0);
return min;
}
void delete(Key e){
if(!map.containsKey(e)) throw new NoSuchElementException(e+" does not exist ");
int j = map.get(e);
swap(j, n-1);
map.remove(e);
n--;
if(!swim(j))
sink(j);
}
void decreasePriority(Key e){
if(map.containsKey(e)){
int j = map.get(e);
swim(j);
}
else insert(e);
}
private void swap(int i, int j) {
Key t = heap[i];
heap[i] = heap[j];
heap[j] = t;
map.replace(heap[i], i);
map.replace(heap[j], j);
}
private boolean swim(int j){
boolean change = false;
int parent;
while( (parent = (j-1)/2 ) >= 0){
if(heap[j].compareTo(heap[parent]) < 0){
swap(j,parent);
j = parent;
change = true;
}
else break;
}
return change;
}
private void sink(int j){
while(j <= n/2 - 1){
int leftChild = j*2 + 1, rightChild = leftChild + 1, s;
if(rightChild >= n)
s = leftChild;
else
s = heap[leftChild].compareTo(heap[rightChild]) < 0 ? leftChild : rightChild;
if(heap[j].compareTo(heap[s]) > 0){
swap(j,s);
j = s;
}
else break;
}
}
#Override
public String toString() {
String res = "[";
int i;
for (i = 0; i < n-1; i++){
res += heap[i] + ", ";
}
res += heap[i]+"]";
return res;
}
}
Edit: Be careful with your class comparator.
I am getting an error:
java.lang.ArrayIndexOutOfBoundsException: -1
and it refers to method inject:
deque[back] = x;
I also have methods for push and pop which add and remove items at the front but those work fine.
The idea is to use an array-based implementation as deque, where inject and eject insert item at the back and remove item at the back.
public void inject(int x){
if (elementCount == size){
System.out.println("The Deque is Full");
} else {
deque[back] = x;
back = (back - 1) % size;
elementCount ++;
}
}
public class Deque {
int[] deque;
int front;
int back;
int size;
int elementCount;
public Deque(int s){
size = s;
deque = new int[size];
front = 1;
back = 0;
elementCount = 0; //n of elements
}
public int getRear(){
return deque[back];
}
public int getFront(){
return deque[front];
}
public void inject(int x){
if (elementCount == size){
System.out.println("The Deque is Full");
} else {
deque[back] = x;
back = (back - 1) % size;
elementCount ++;
}
}
public void eject(){
if (elementCount == 0){
System.out.println("The deque is empty");
}else{
back = (back + 1) % size;
elementCount--;
}
}
}
You have in multiple places:
back = (back - 1) % size;
That doesn't work like you think it does when back is originally 0, where it becomes -1 % size, which is usually -1. In the places where it appears, you should instead use:
back = (size + back - 1) % size;
First thing I notice is you are using too many variables for this problem. If you break it down you only need 3 variables. the array, the size of the array and current location in the array for inject and eject. This is a LiFo( Last in First Out) order.
public void inject(int x){
if (this.deque.size() == this.size){ //check for full array
System.out.println("The Deque is Full");
} else {
this.deque[this.back+1] = x; //input new item next slot
this.back ++; //increment back to new input where eject would pull from
}
}
public class Deque {
int[] deque;
int back;
int size;
public Deque(int s){
this.size = s;
this.deque = new int[size];
this.back = 0;
}
this should also solve your array index issue I am not sure why you were using a Modulo function '%' for the current location of back.
Going through some past Java exercises so I can improve my programming in general and I've been stuck on this for quite a while. I'm going to post all of the source that's required, since this project is quite large and there's a lot of interfaces and subclasses that just offer to confuse.
public class Board {
public final static char NOUGHT = 'O';
public final static char CROSS = 'X';
public final static char EMPTY = ' ';
// Each cell is indexed as follows:
// 1 2 3
// 4 5 6
// 7 8 9
private char[][] grid; // a matrix to store the positions of the board
private int numOfMarks; // number of moves made on the board
private int lastMarkPosition; //position of last move maode in the board
public Board() {
grid = new char[3][3];
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
grid[row][col] = EMPTY;
}
}
numOfMarks = 0;
lastMarkPosition = 0;
}
//post: Returns true if the board is finished.
// A board is finished because either there is a winner or the board is full.
public boolean isFinished() {
return numOfMarks == 9 || getWinnerMark() != EMPTY;
}
//post: Records the position of the last mark made on the board.
public void setLastMarkPosition(int lastPosition){
lastMarkPosition = lastPosition;
}
//post: Returns the position of the last mark
public int getLastMarkPosition(){
return lastMarkPosition;
}
//post: Returns the mark ('X' or 'O') of the winner player if a winning condition exists in the board,
// returns EMPTY otherwise.
public char getWinnerMark() {
for (int i = 0; i < 3; i++) {
// check if there are three in a horizontal row
if (grid[i][0] != EMPTY && grid[i][0] == grid[i][1]
&& grid[i][1] == grid[i][2]) {
return grid[i][0];
}
// check if there are three in a vertical row
if (grid[0][i] != EMPTY && grid[0][i] == grid[1][i]
&& grid[1][i] == grid[2][i]) {
return grid[0][i];
}
}
// check if there are three in a diagonal row
if (grid[1][1] != EMPTY
&& (grid[1][1] == grid[0][0] && grid[1][1] == grid[2][2] || grid[1][1] == grid[0][2]
&& grid[1][1] == grid[2][0])) {
return grid[1][1];
}
// otherwise, return EMPTY as there is no winner
return EMPTY;
}
//post: Sets the given mark at the given position in the board
public void setMark(int pos, char mark) throws GameException {
if (numOfMarks == 9) {
throw new GameException("attempted to set mark on a full board.");
}
if (pos < 1 || pos > 9) {
throw new GameException(
"attempted to set mark in a wrong position: " + pos);
}
if (mark != NOUGHT && mark != CROSS) {
throw new GameException("attempted to set an invalid mark: "
+ String.valueOf(mark));
}
// perform board update
int row = (pos - 1) / 3;
int col = (pos - 1) % 3;
if (grid[row][col] != EMPTY) {
throw new GameException(
"attempted to set mark on a non-empty position: "
+ pos);
} else {
grid[row][col] = mark;
numOfMarks++;
}
}
//post: Returns the mark that is at a given position in the board
public char getMark(int pos) {
return grid[(pos-1)/3][(pos-1)%3];
}
//post: If the grid is not full, calculates whose turn is, based on the marks in the grid.
// Returns EMPTY if the board is already full.
public char getTurn() {
if (numOfMarks == 9) {
return EMPTY;
} else if (numOfMarks % 2 == 0) {
// by default, CROSS should go first
return CROSS;
} else {
return NOUGHT;
}
}
//post: Copy the board and returns it
public Board makeCopy() {
Board copy = new Board();
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
copy.grid[row][col] = this.grid[row][col];
}
}
copy.numOfMarks = this.numOfMarks;
return copy;
}
//post: Prints the given board
public static void display(Board board) {
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
System.out.print(" ");
char mark = board.grid[row][col];
if (mark != EMPTY) {
System.out.print(mark);
} else {
System.out.print((row)*3+(col+1));
}
System.out.print(" ");
if (col < 2) {
System.out.print("|");
}
}
System.out.println();
if (row < 2) {
System.out.println("-----------");
}
}
}
GameTreeInterface
public interface GameTreeInterface {
//post: Returns the board at the root of the game tree.
public Board getRootItem();
//post: Expands the game tree fully by adding all possible boards in the game.
// It uses a recursive auxiliary method.
public void expand();
//pre: The game tree is fully expanded.
//post: Assigns a score to each board in the game tree.
// It uses a recursive auxiliary method.
public void assignScores();
//pre: Each board in the game tree has a score.
//post: Computes an array of positions (1..9) optimal available moves.
// These are the last mark positions in the children boards that have the highest score.
public int[] BestMoves();
//post: Returns the number of boards stored in a game tree.
// It uses a recursive auxiliary method.
public int size();
}
GameTree
public class GameTree implements GameTreeInterface {
private GameTreeNode root; // reference to the root board of a game tree
public GameTree(Board board) {
this.root = new GameTreeNode(board);
}
// post: Returns the board at the root of a game tree.
public Board getRootItem() {
return root.getBoard();
}
// post: Returns the number of boards stored in a game tree.
// It uses a recursive auxiliary method.
public int size() {
return sizeTree(root) + 1;
}
// post: Returns the number of boards stored in a game tree, excluded
// the root.
private int sizeTree(GameTreeNode node) {
int total = 0;
for (int i = 1; i < node.numberOfChildren(); i++) {
if (node.getChild(i).getBoard() != null)
total++;
}
return total;
}
// post: Expands the game tree fully by adding all possible boards in
// the game.
// It uses a recursive auxiliary method.
public void expand() {
expandTree(root);
}
// post: Expands the game tree from the given node by adding
// all the possible moves that the computer and the user player
// can make, until the game is finished, from the given node onwards.
private void expandTree(GameTreeNode node) {
if (!node.getBoard().isFinished()) {
char c = node.getBoard().getTurn();
for (int i = 1; i < 9; i++) {
if (node.getBoard().getMark(i) == Board.EMPTY) {
GameTreeNode n = new GameTreeNode(node.getBoard());
n.getBoard().setMark(i, c);
n.getBoard().setLastMarkPosition(i);
node.getChildren().add(2, n);
expandTree(n);
}
}
}
}
// pre: The game tree is fully expanded.
// post: Assigns a score to each board in the game tree.
// It uses a recursive auxiliary method.
public void assignScores() {
char player = (root.getBoard()).getTurn();
assignScoresTree(root, player);
}
// post: Assigns scores to each board in a game tree for the computer
// player.
private void assignScoresTree(GameTreeNode node, char player) {
Board board = node.getBoard();
if (board.isFinished()) {
// base case of recursion
// score 3 for a winning board for the given player,
// score 2 for a draw baord,
// score 1 for a losing board for the given player
char winner = board.getWinnerMark();
if (winner == Board.EMPTY) {
// this is a draw!
node.setScore(2);
} else {
node.setScore(winner == player ? 3 : 1);
}
}
else {
// tries to assign the scores to all the children boards
// first, recursively
int minScore = Integer.MAX_VALUE;
int maxScore = Integer.MIN_VALUE;
GenericList<GameTreeNode> children = node.getChildren();
for (Iterator<GameTreeNode> it = children.iterator(); it
.hasNext();) {
GameTreeNode child = it.next();
assignScoresTree(child, player);
// keeps track of the maximum and minimum scores
// of the children boards so far
int childScore = child.getScore();
if (childScore > maxScore)
maxScore = childScore;
if (childScore < minScore)
minScore = childScore;
}
// Assigns score to the current board in the recursion
// according to the player's turn
if (board.getTurn() == player) {
// get the maximum score as the player wants to
// win
node.setScore(maxScore);
} else {
// get the minimum score (as the player wants
// the opponent to lose;)
node.setScore(minScore);
}
}
}
// pre: Each board in the game tree has a score.
// post: Computes an array of positions (1..9) optimal available moves.
// These are the last mark positions in the children boards that have
// the highest score.
public int[] BestMoves() {
int maxScore = Integer.MIN_VALUE;
GenericList<GameTreeNode> highestScoreBoards = new GenericList<GameTreeNode>();
GenericList<GameTreeNode> children = root.getChildren();
for (Iterator<GameTreeNode> it = children.iterator(); it
.hasNext();) {
GameTreeNode nextBoard = it.next();
int curScore = nextBoard.getScore();
if (maxScore < curScore) {
maxScore = curScore;
highestScoreBoards.clear();
highestScoreBoards.add(1, nextBoard);
} else if (maxScore == curScore) {
highestScoreBoards.add(1, nextBoard);
}
}
int[] moves = new int[highestScoreBoards.size()];
for (int i = 0; i < moves.length; i++) {
Board board = (highestScoreBoards.get(i + 1))
.getBoard();
moves[i] = board.getLastMarkPosition();
}
return moves;
}
}
GameTreeNode
public class GameTreeNode{
private GameTreeItem item; // includes the board object and the score
private GenericList<GameTreeNode> children; //list of gameTreeNodes of possible next moves.
public GameTreeNode(Board newBoard) {
this.item = new GameTreeItem(newBoard);
this.children = new GenericList<GameTreeNode>();
}
//post: Returns the board stored in a GameTreeNode
public Board getBoard() {
return item.board;
}
//post: Returns the children stored in a GameTreeNode, as a list of GameTreeNodes
public GenericList<GameTreeNode> getChildren(){
return children;
}
//post: Returns the score of the board
public int getScore() {
return item.score;
}
//post: Sets the score of the board to be equal to the given score
public void setScore(int score) {
item.score = score;
}
//post: Removes all the children
public void removeChildren(){
children = null;
}
//post: Returns the number of children
public int numberOfChildren(){
return children.size();
}
//post: Returns the child at a given position in the list of children, as a
GameTreeNode
public GameTreeNode getChild(int i){
return children.get(i);
}
//Inner class for storing a board and the score
private class GameTreeItem{
private Board board;
private int score;
public GameTreeItem(Board newBoard) {
this.board = newBoard;
score = 0;
}
}
Apologies for the rather large amount of code but I don't think I could explain the problem without having everything here. There's still a lot of extra code for the GenericList but it's a pretty straightforward implementation for a generic linked list.
If anyone does go through this code, my problem is in the GameTree class with the sizeTree() method. I offered a solution but I think it's far too simple to be correct. As I understand it, a GameTreeNode includes a GameTreeItem containing the current state of play and a reference to a linked list of GameTreeNode. However, my specification says that I have to use recursion to implement this method but I'm not sure how. Would my method work since it goes through every single child of the root and checks for the boards?
I know it's a long shot but if anyone can offer any help I'd really appreciate it!
Hello fellow programmers.
I am having a very silly problem.. I'm supposed to sum all the integers in a List, recursively. I know that there is an easier way to do this, and I actually made that method too (see class below). But the meaning of this assignment is that I have to split the list up into 2 halves and then calculate the sum recursively on both halves, and last I just return half1 + half2.
The problem is that the advanced method does not return the sum of all values. Can anyone please help me?
The method sum is the simple method. Summer(Summarize in danish) is the more advanced method.
package opgave1;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class BinærSøgning {
public static void main(String[] args) {
Random random = new Random();
int tal = 3;
List<Integer> liste = new ArrayList<Integer>();
for (int i = 0; i < 10; i++)
liste.add(random.nextInt(10));
Collections.sort(liste);
System.out.println(liste);
// System.out.println(binærSøgning(liste, 0, tal));
System.out.println(summer(liste, 0));
}
public static int binærSøgning(List<Integer> liste, int start, int find) {
if (liste.size() > 0) {
int midt = liste.size() / 2;
if (liste.get(midt) == find)
return start + midt;
else if (liste.size() > 1) {
if (find < liste.get(midt))
return binærSøgning(liste.subList(0, midt), start, find);
else
return binærSøgning(liste.subList(midt + 1, liste.size()), start + midt + 1, find);
}
}
return -1;
}
public static int sum (List<Integer> list, int i)
{
if (i == list.size())
return 0;
else
return list.get(i) + sum(list, i+1);
}
public static int summer(List<Integer> list, int start){
int right = 0;
int left = 0;
if(start == list.size()){
return 0;
} else {
int mid = list.size() / 2;
if(start < mid){
left += list.get(start) + summer(list.subList(0, mid), start+1);
} else if(mid < list.size()){
right += list.get(mid) + summer(list.subList(mid+1, list.size()), mid+1);
}
}
return right + left;
}
}
Ii's much easier with two base cases, there is no need for an extra 'start' parameter if you use sublists. (Because it's homework, I won't fill in the details.)
public static int summer(List<Integer> list) {
//base 1
if (list.size() == 0) {
}
//base 2
else if (list.size() == 1) {
}
else
{
//no need for if statements now!
int left = summer(list.sublist(/* */))
int right = summer(list.sublist(/* */))
return left + right;
}
}
Are you sure that you have to split the list? Usually, when you get this task for homework, the meaning is something like:
public static int sum(List<Integer> l,int start) {
if (start==l.size()) return 0;
return l.get(start)+sum(l,start+1);
}
You are missing out elements of list when you are sending start+1 in the recursion.
left += list.get(start) + summer(list.subList(0, mid), start+1);
You should rather send
left += list.get(0) + summer(list.subList(1, mid), 0);
and
right += list.get(mid) + summer(list.subList(mid+1, list.size()), 0);
I dont see the need to sending any start value. Every recursion should take the 0 in place of start.
I think it can be solved in a simpler way, by keeping track of both the first and last index of the range, like this:
public static int sum(List<Integer> list, int i, int j) {
if (i == j)
return list.get(i);
int half = (i + j) / 2;
return sum(list, i, half) + sum(list, half + 1, j);
}
It's called like this:
List<Integer> list = Arrays.asList(1, 2, 3);
System.out.println(sum(list, 0, list.size()-1));
It will work fine for non-empty lists. If the list is empty, you'll need to check it before calling sum.
First of all, you don't need to cut the list in half if all you need to do is use recursion. The sum of the elements of a list is the sum of its first element + the sum of all the elements of the rest of the list.
Second, your method is too complex. The sum of the elements of the list is 0 if the list is empty, the unique element is it contains 1 element, and the sum of the results of the method applied to the two sublists if it contains more than 1. You don't need any start argument.
This should get you started.
EDIT: since Oscar Lopez gave you the answer, but I find it too complex, here's mine:
public static int sum(List<Integer> list) {
if (list.isEmpty()) {
return 0;
}
else if (list.size() == 1) {
return list.get(0);
}
else {
int half = list.size() / 2;
return sum(list.subList(0, half)) + sum(list.subList(half, list.size()));
}
}
I am wondering a reason of getting a "half" of the List.The solution for the question is the one and only:
public int sum_list(List<Integer> list) {
if (list == null || list.isEmpty()) {
return 0;
}
return list.remove(0) + sum_list(list);
}
import java.util.*;
public class SumListByRecursion {
public static int sumByRec(List<Integer> list) {
int size = list.size();
if(size > 0) {
return list.get(0) + sumByRec(list.subList(1, size));
}
return 0;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
System.out.println("List:"+" "+list);
int sum = sumByRec(list);
System.out.println("Sum of the list:"+" "+sum);
}
}
You can use this method for sum all ement of given list.
public static Integer sumOfList(List<Integer> list){
try {
return list.get(0) + sumOfList(list.subList(1, list.size()));
}catch (Exception e) {
return 0;
}
}