I'm in an intro to Java course and am just trying to get ahead of the curve with some practice, so I'm making a bubble sort program. For some reason, it only will run through the outer loop twice.
public ArrayList SortArray(ArrayList<Integer> u) {
int temp;
int spot;
for (int isOrdered = 1; isOrdered == 1;) {
for (spot = 0; spot < u.size() - 1; spot ++) {
System.out.println(u.get(spot) + " " + u.get(spot + 1) + " " + spot);
if (u.get(spot) > u.get(spot + 1)) {
temp = u.get(spot + 1);
u.set(spot + 1, u.get(spot));
u.set(spot, temp);
isOrdered = 1;
}
else {
isOrdered = 0;
}
}
}
return u;
}
As far as I can tell, what's happening is after the second iteration, it doesn't reset 'spot' to 0 so it doesn't run through the loop again. Any ideas?
Well, for starters that's an ... unusual way of using a for loop to implement a while loop. Try using a boolean for isOrdered and a while(!isOrdered) for a statement like that.
As Ted Hopp's comment said, your logic isn't quite right. What your code is doing is that it will sort ONE value in the list and once that value has "bubbled up" your flag is set to true.
You need your outer loop's condition to be that it keeps running until ALL cells are in order.
Right now your flag simply says it's sorted, when you've gone through the list, but what it needs to do is be true when it's gone through the list without performing a swap.
Try to implement that without looking, then if you can't get it (I'm assuming you're interested in doing it yourself since you're working ahead in your class) take a look at the sample here.
Related
When creating the following function, in order to get a correct answer I have to add "count-=1" line, otherwise the answer gets skewed by 1.
public int countCTG(String dna) {
int count = 0;
int firstOccurrence = dna.indexOf("CTG");
if (firstOccurrence != -1) {
count +=1;
while (dna.indexOf("CTG", firstOccurrence) != -1 && firstOccurrence != -1) {
count +=1;
firstOccurrence = dna.indexOf("CTG", firstOccurrence+3);
}
count -=1;
}
else {
count = 0;
}
return count;
}
I managed to get this function working, however could you please help me understand the logic behind it? The count variable was initialized originally to 0 and if a string,for example, contains one instance of "CTG" it will be already counted in by "count +=1" line. Wouldn't count -=1 reset this variable back to 0?
You need the -1 because of the +1 before the loop: the first iteration of the while loop counts the already-found occurrence again.
An easier solution is like so:
int count = 0;
int skip = "CTG".length();
int current = -skip;
while ((current = dna.indexOf("CTG", current + skip)) >= 0) {
++count;
}
return count;
Because you're not updating firstOccurrence after your first search -- i.e. you're searching twice from the start (.indexOf("CTG")) before starting to search from the previous result (.indexOf("CTG", prevResultIndex + 3)).
Also note that:
you don't have to search once before the while loop
the else clause is redundant
you're calling .indexOf twice as many times as you actually need
the firstOccurrence+3 is a liability, you'll forget to update the offset when the string changes and it will be hard to track down. Store the searched-for string in one place, and compute its length instead of hardcoding it.
EDIT: Well #AndyTurner rewrote it for you, but try to see how each one of the listed points come into reaching that result
I just finished studying the simple BinarySearch algorithm, but one thing that bugs me is that I was taught that break (and continue) statements are often redundant in Java and you can do with most while-loops without them. But I can't figure out how to get rid of hem from the BinarySearch while-loop below:-
public static void BinarySearch(int[] list, int key){
int lo = 0;
int hi = list.length-1;
int mid = 0;
while(lo<=hi){
mid = lo + (hi-lo) / 2;
if(key<list[mid])
hi = mid-1;
else if(key>list[mid])
lo = mid+1;
else {
System.out.println("Key is found at index = " + mid);
break;
}
if(lo>hi){
System.out.println("Key doesn't exist in the list");
}
}
Question 1: Why does the loop keeps going on and on if I didn't include the break statement? Shouldn't the variable "lo" eventually become greater than "hi"? How come the last if- conditional can see that, but not the while-loop-conditional?
Question 2: How can I can type the while-loop without needing the break statement?
The basic strategy is to add extra conditions to the loop, and set and use these conditions in the code within the loop.
For example, for the above loop:
int keyIndex = -1;
. . .
while ( (lo<=hi) && (keyIndex == -1) ) {
. . .
else {
System.out.println("Key is found at index = " + mid);
keyIndex = mid; // <<<
}
. . .
}
However, using a break statement for loops such as this is considered an acceptable programming practice by many developers.
Here is a reddit discussion on the use of break and continue.
And here is a question in the sister site on software engineering.
As to why your loop does not exit without the break statement is if the key is found, the value of lo is not changed. So no, the value of lo does not necessarily become greater than high.
I was tasked to create a simulation of a Bank. So far the progress I've made are generating random Client objects, making 4 objects of Teller, putting the Client objects into a circular queue and putting a Client into an empty Teller if there are any.
The problem I have now is that the while loop I made does no continue even though the set condition is still true, it can only execute 5 times. The program still runs though.
This is the code I have so far(assume all variables are declared):
public void run() {
int counter = 1;
populateTellers(windowArray);
while (counter < 10) {
newClient = generateClient();
System.out.println(newClient.toString() + " arrived at :" + counter);
System.out.println();
clientQueue.enqueue(newClient);
clientList.add(newClient);
System.out.println("The Queue now contains " + clientQueue.numberOfOccupiedCells() + " Client(s):");
for (int x = 0; x < clientList.size(); x++) {
System.out.println(clientList.get(x).toString());
}
System.out.println();
arrayIndex = getATeller(windowArray);
if (arrayIndex != -1) {
clientList.remove(0);
clientQueue.dequeue();
windowArray[arrayIndex].setClient(newClient);
windowArray[arrayIndex].setServiceTime(newClient.getDuration());
System.out.println(windowArray[arrayIndex].getName() + " now serves " + newClient.toString());
} else {
for (int x = 0; x < clientList.size(); x++) {
if (windowArrray[arrayIndex].getServiceTime() == counter) {
windowArray[arrayIndex].setClient(new Client());
System.out.println(windowArray[arrayIndex].getName() + " ends service for " + newClient.toString());
}
}
}
counter++;
}
}
The one thing that I can't get head around is that when I remove the code from aI = getATeller(wA); 'till the closing bracket of the if statement below it the program would work. I've tried putting the block into a method, changing the positions of the codes inside if(){} and else{} and changing the condition to if(aI==1), still I got no improvements. Any idea on what I'm doing wrong?
EDIT: So I've been able to narrow it down to a line of code which is windowArray[arrayIndex].setServiceTime(newClient.getDuration());, whenever I assign a value to a Teller's service time the problem would occur, I've checked my Teller class and there was no error there. Any ideas how I can solve this.
Why is it only executing 5 times? According to the code, counter is used as the used to check if it should continue looping for not. The only instance where counter is changed is at last line: counter++.
I can guess that you did a System.out.print on the counter, and it ends up to 5, and it magically stops. Most likely it's throwing an exception, which is not caught, and is lost in the void.
Edit: If this piece of code is being run on another thread, then maybe it's hanging up on some function. Do as told here
Try to find where your loop was turning to infinite loop,
Try writing printing statements, wherever necessary, just to find the flow of execution.
Then printout your variable values, too check whether they were as expected, keep on narrowing your scope as you find error occurred in certain scope, then you will find the culprit, if it is leading you to some other function, then thoroughly check that particular function.
I was trying to implement the coin change problem using recursion. I have written the following code and am facing a problem with the static class variable. 'answer' is a class variable and i am trying to add the return value to it in the loop. This works fine within the while loop but after the while loop ends the answer is reset to 0;
while (i * currentCoin <= sum) {
System.out.println("inside while; answer is " + answer);
answer = answer
+ findCombinations(
sum - i * currentCoin,
new ArrayList<Integer>(denominations.subList(1,
denominations.size())));
i++;
}
Below is all the code that I have written. You can copy and run it to check.
import java.util.ArrayList;
import java.util.Collections;
public class CoinChangeHashMap {
static int answer = 0;
public static void main(String[] args) {
int[] array = new int[] { 7, 3, 2 };
ArrayList<Integer> input = new ArrayList<Integer>();
getList(array, input);
findCombinations(12, input);
System.out.println(answer);
}
private static void getList(int[] array, ArrayList<Integer> input) {
for (int i : array) {
input.add(i);
}
}
public static int findCombinations(int sum, ArrayList<Integer> denominations) {
if (denominations.size() == 1) {
if (sum % denominations.get(0) == 0) {
return 1;
}
return 0;
}
int i = 0;
int currentCoin = denominations.get(0);
while (i * currentCoin <= sum) {
System.out.println("inside while; answer is " + answer);
answer = answer
+ findCombinations(
sum - i * currentCoin,
new ArrayList<Integer>(denominations.subList(1,
denominations.size())));
i++;
}
return 0;
}}
**The output that I get is 0. but the expected output is 4. While debugging the output that I got is **
inside while; answer is 0
inside while; answer is 0
inside while; answer is 1
inside while; answer is 1
inside while; answer is 2
inside while; answer is 2
inside while; answer is 0
inside while; answer is 0
inside while; answer is 0
0
Any Help is appreciated.
The problem is related to your odd code structure, in which you convey the outcome of your recursive call sometimes by modifying static variable answer, and sometimes via the method's return value.
If you analyzed the problem more closely, you would discover that it is not upon exit from the loop that the partial results are lost, but rather some time after return from the method. Therefore, consider carefully the way you update the answer:
answer = answer + findCombinations( /* ... */ );
At the top-most level of your recursion, answer is initially 0. When Java evaluates the above expression, it evaluates first the left operand and then the right operand, then it adds them. That is, it evaluates answer, getting the result 0, before it performs the recursive call. The value of answer may be updated in the course of the recursive call, but those changes come too late. Only the bottom-most level of the recursion ever returns a value different from zero, so if the recursive call itself recurses at least one level deeper then it will return zero. In that case, the sum is computed as 0 + 0, and assigned to answer, clobbering any update the method performed.
You could resolve the problem by swapping the order of the operands in your sum, but it would be better, and not much harder, to get rid of the static variable altogether. Use a local variable within the method to accumulate results, and in all cases convey the total back to the caller via the method's return value.
recently I've been trying to teach myself a bit of recursion to understand the process better. While I understand basic recursion techniques, I still struggle quite a bit with the idea of recursive backtracking. In order to help this, I've attempted to program a method that solves a sudoku solver when given a 2D array and and two ints, r and c, which are meant to represent the current column and row.
I have everything set up properly I believe, yet I can't quite figure out how to handle the "unraveling", or what happens after my initial method calls reach the eventual base case.
As of right now, when I run this method, it just returns a board that's empty, (unless there was previously a value there before, in which case it remains unchanged). I feel like the "board[r][c] = 0" that I have at the end of the method might have something to do with that.
The method "digitsValid" corresponds to a method that checks to make sure the current location on the board is a valid move within the row, column, and 3x3 subgrid.
Any help would be much appreciated.
private boolean sudokuSolver(int[][] board, int r, int c) {
if(c > 8) {
c = 0;
r = r + 1;
}
if(r > 8) {
return true;
}
if(board[r][c] != 0) {
sudokuSolver(board, r, c + 1);
} else {
for(int i = 1; i <= 9; i++) {
if(digitsValid(board, r, c)) {
board[r][c] = i;
if(sudokuSolver(board, r, c + 1)) {
return true;
}
}
}
}
board[r][c] = 0;
return false;
}
I think your original assessment is correct. Recursive methods sound confusing but think of them like this:
public class RecursiveTest{
public static void main(String[] args){
int x = 5;
recursiveMethod(x);
}
public static void recursiveMethod(int i){
System.out.println("Method just started for i = " + i);
if(i > 0)
recursiveMethod(i - 1);
System.out.println("Method just ended for i = " + i);
}
}
Yields the following output:
Method just started for i = 5
Method just started for i = 4
Method just started for i = 3
Method just started for i = 2
Method just started for i = 1
Method just started for i = 0
Method just ended for i = 0
Method just ended for i = 1
Method just ended for i = 2
Method just ended for i = 3
Method just ended for i = 4
Method just ended for i = 5
Explanation
A recursive method is not all that different from any other method. It executes some code, at some point calls a method, runs that method and then continues running the rest of the code and finishes where any other method would finish.
The only difference is that method call is a call to itself. This would work the same as if you had copy-pasted that same method 5 times and named it all something different and then "daisy chained" them together.
In the example above, the original value is 5, it prints out that it started the for i=5, then ran the same method with the value of 4. Printed that, then ran 3 etc. Once it reached the final value where i = 0 the if statement failed and therefore it stopped the recursive calls. The method we are currently in (i = 0) finishes by writing Method just ended for i = 0 then it returns to the calling method when i = 1 and back tracks the same way it went in.
Your Code
I'm not quite sure what you have going on here. Does your example work? I'd like to see the isValid() method, but the following code you have:
for(int i = 1; i <= 9; i++) { // Runs the following code 9 times.
if(digitsValid(board, r, c)) { // if true once, true every time
board[r][c] = i;
if(sudokuSolver(board, r, c + 1)) { // this is a totally separate method
return true;
}
}
}
Your loop runs 9 times. The if statement following it never changes. The values within are not edited within the loop, so if it evaluates to true when i = 1 then it's going to evaluate to true on all 9 iterations of the for loop. This means the value at board[r][c] is going to end on 9.
From the looks of it, the only way this will ever return false, is if there is an invalid digit already stored in the array at the time of calling the method.