This is my Java code for eight queens. I don't know why it place same results for eight times.
In this code, diagonal is not included.
import java.util.*;
class eightTeight {
Set<Integer> s = new HashSet<Integer>();
public void print() {
if (s.size() < 8) {
for (int i = 0; i < 8; i++) {
if (!s.contains(i)) {
s.add(i);
print();
}
}
}
System.out.println(s);
return;
}
}
It seems that once return runs, the s still keeps the data. Appreciated to any help.
In Java, when you pass the object to the method, you copy the reference to the object. So, changes made to the object are visible by all references to that object (including the one you keep in the calling method).
There are two solutions for it:
Copy the HashSet before doing modifications, and do the modifications to the copy. In case a solution is found, return the new copy. In case it does not work, return the original copy.
Use a data structure thtat depends in an index, so you can ignore all values that should not still be set. For example an array, if you are iterating for the 5th queen you can ignore the values of the fifth, sixth, seventh and eighth queens if they are set.
I find more clear the queens problem implemented with an int array, but that is left to everybodys taste.
It caused by your recursively invoking
print();
And you should realize that there is no global variable in JAVA. Every time you invoke "print()" will just use the empty "Set", then you add sth into it, and print it out. There are eight times recursion here, therefore there are eight times that console print out the same thing. This is why your fail the expectation.
"I don't know why it place same results for eight times".
Because you are calling the method recursively 8 times, and for each time it prints the result.
for(int i=0;i<8;i++){
if(!s.contains(i)){
s.add(i);
print();
}
}
Take the print to outside the method.
Related
Started learning about loops and the different types today. My question is in this situation which type would i try to use? And what would be the advantage over the others? After looking over my lecture notes it seems that do-while should always be used but I'm certain that it is not the case.
Also how would I start that first one about returning a sum of the "given array." what is the given array? Is it just whatever I'm supposed to be plugging into the run arguments line?
public class SumMinMaxArgs {
// TODO - write your code below this comment.
// You will need to write three methods:
//
// 1.) A method named sumArray, which will return the sum
// of the given array. If the given array is empty,
// it should return a sum of 0.
//
// 2.) A method named minArray, which will return the
// smallest element in the given array. You may
// assume that the array contains at least one element.
// You may use your min method defined in lab 6, or
// Java's Math.min method.
//
// 3.) A method named maxArray, which will return the
// largest element in the given array. You may
// assume that the array contains at least one element.
// You may use your max method defined in lab 6, or
// Java's Math.max method.
//
// DO NOT MODIFY parseStrings!
public static int[] parseStrings(String[] strings) {
int[] retval = new int[strings.length];
for (int x = 0; x < strings.length; x++) {
retval[x] = Integer.parseInt(strings[x]);
}
return retval;
}
// DO NOT MODIFY main!
public static void main(String[] args) {
int[] ints = parseStrings(args);
System.out.println("Sum: " + sumArray(ints));
System.out.println("Min: " + minArray(ints));
System.out.println("Max: " + maxArray(ints));
}
}
All three forms have exactly the same expressive power. What you use in a certain situation depends on style, convention, and convenience. This is much like you can express the same meaning with different english sentences.
That said, do - while is mostly used when the loop should run at least once (i.e. the condition is checked only after the first iteration).
for is mostly used when you are iterating over some collection or index range.
The four kinds of loops supported in Java:
C-style for loop: for (int i = 0 ; i < list.size() ; ++i) { ... } when you want to access the index of some kind of list or array directly, or to do an operation multiple times.
foreach loop, when you want to iterate over a collection, but don't care about the index: for (Customer c : customers) { ... }
while loop: while (some_condition) { ... } when some code must executed as long as the condition is true. If the condition is false to start with, the code inside the block (i.e. inside the brackets) will never be executed.
do while loop: do { statement1; } while (condition); will execute statement1 even if the condition is false to begin with, but it will do so only once.
Say, I'm making a simple badugi card game where the Hand is represented by 10 characters in a string. E.g:
2s3h5dQs - 2 of spades, 3 of hearts, 5 of diamonds, Queen of spades
Now, in this badugi card game I want to create two loops where the first loop checks if all the ranks are different(none of them can be the same) and the other loop checks if all the suits are different. If both of these conditions return as true where they all have different ranks and suits, the hand has drawn a badugi(please excuse my lack of terminology where necessary.)
Now, how can I create an efficient loop for such a situation? I was thinking that I could create several if statements as such:
if (hand.charAt(0) != hand.charAt(2) && hand.charAt(0) != hand.charAt(4) && hand.charAt(0) != hand.charAt(6))
if (hand.charAt(2) != hand.charAt(0) && hand.charAt(2) != hand.charAt(4) && hand.charAt(2) != hand.charAt(6))
... and so forth comparing every single index to one another. But this gets tedious and seems very unprofessional. So my question is, how do I write an efficient loop for this scenario? How can I compare/check if there are no matches at these specific index points to one another?
If I haven't explained properly then please let me know.
Please keep in mind, I am not allowed freedom of how to formulate a hand. It has to be in the format above
You are putting your energy into the wrong place.
You do not need to worry about efficiency at all.
Instead, you should worry about creating a clean design (based on reasonable abstractions) and then write code that is super-easy to read and understand.
And your current approach fails both of those ideas; unfortunately completely.
In other words: you do not represent hands and values as characters within a String.
You create a class that abstracts a Card (with its value and face).
And then a "hand" becomes a List / array of such Card objects. And then you can use concepts such as Comparator to compare card values, or you can make use of equals() ...
And even when you wish to keep your (actually over-complex) naive, simple approach of using chars within a string; then you should at least use some kind of looping so that you don't compare charAt(0) against charAt(2); but maybe charAt(i) against charAt(j).
And following your edit and the excellent comment by jsheeran: even when you are forced to deal with this kind of "string notation"; you could still write reasonable code ... that takes such string as input, but transforms them into something that makes more sense.
For example, the Card class constructor could take two chars for suite/value.
But to get you going with your actual question; you could something like:
public boolean isCardDistinctFromAllOtherCards(int indexToCheck) {
for (int i=0; i<cardString.length-1; i+=2) {
if (i == indexToCheck) {
continue;
}
if (cardString.charAt(indexToCheck) == cardString.charAt(i)) {
return false;
}
}
return true;
}
( the above is just an idea how to write down a method that checks that all chars at 0, 2, 4, ... are not matching some index x).
You should really think about your design, like creating Card class etc., but back to the question now, since it's not gonna solve it.
I suggest adding all 4 values to a Set and then checking if size of the Set is 4. You can even shortcut it and while adding this yourSet.add(element) return false then it means there is already that element in the set and they are not unique. That hardly matters here since you only need to add 4 elements, but it may be useful in the future if you work with more elements.
I would advice creating an array with these chars you are referencing just to clean up the fact you are using indices. i.e create a vals array and a suits array.
This would be my suggestion by using a return or break the loop will stop this means when a match is found it wont have to loop through the rest of the elements .. Hope this helps !
private static int check(char[] vals, char[] suits){
int flag;
for(int i=0; i<=vals.length-2;i++){
for(int k=vals.length-1; k<=0;k++){
if(vals[i]==vals[k]){
flag=-1;
return flag;
}
if(suits[i]==suits[k]){
flag=1;
return flag;
}
}
}
return 0;
}
Why not simply iterate over your string and check for same ranks or suits:
public class NewClass {
public static void main(String[] args) {
System.out.println(checkRanks("2s3h5dQs"));
System.out.println(checkSuits("2s3h5dQs"));
}
public static boolean checkRanks(String hand){
List<Character> list = new ArrayList<>();
for (int i = 0; i< hand.length(); i+=2){
if (!list.contains(hand.charAt(i))){
list.add(hand.charAt(i));
}
else{
return false;
}
}
return true;
}
public static boolean checkSuits(String hand){
List<Character> list = new ArrayList<>();
for (int i = 1; i< hand.length(); i+=2){
if (!list.contains(hand.charAt(i))){
list.add(hand.charAt(i));
}
else{
return false;
}
}
return true;
}
}
if I have a for loop like...
for (int i = 0; i < myArray.length; i++) { ... }
...does myArray.lengthget evaluated every iteration? So would something like...
int len = myArray.length;
for (int i = 0; i < len; i++) { ... }
... be a small performance increase?
regardless myArray.length is just a field so there is nothing to evaluate
Java array has length as public final int so it gets initialized once and when you refer to it there is no code execution like a method call
The public final field length, which contains the number of components of the array. length may be positive or zero.
The first form will probably incur some performance penalty, since evaluating it will require, before the iflt, an aload, an arraylength and an iload; whereas the second is only two iloads.
#ajp rightly mentions that myArray may change; so it is highly unlikely that the compiler will optimize the first form into the second for you (unless, maybe, myArray is final).
However, the JIT, when it kicks in, is probably smart enough so that, if myArray doesn't change, it will turn the first form into the second.
Just in case, anyway, use the second form (this is what I always do, but that's just out of habit). Note that you can always javap the generated class file to see the generated byte code and compare.
By the way, Wikipedia has a very handy page listing all of a JVM's bytecodes. As you may see, quite a lot of them are dedicated to arrays!
Yes, the termination expression gets evaluated every time. So you're right that storing the length once could be a small performance increase. But more importantly, it changes the logic, which could make a difference if myArray gets reassigned.
for (int i = 0; i < myArray.length; i++) {
if (something-something-something) {
myArray = appendToMyArray(myArray, value); // sets myArray to a new, larger array
}
}
Now it makes a big difference whether you store the array length in a variable first.
You wouldn't normally see code like this with an array. But with an arrayList or other collection, whose size could increase (or decrease) in the body of the loop, it makes a big difference whether you compute the size once or every time. This idiom shows up in algorithms where you keep a "To-Do list". For example, here's a partial algorithm to find everyone who's connected directly or indirectly to some person:
ArrayList<Person> listToCheck = new ArrayList<>(KevinBacon);
for (int i = 0; i < listToCheck.size(); i++) {
List<Person> connections = allConnections(listToCheck.get(i));
for (Person p : connections) {
if ([p has not already been checked]) {
listToCheck.add(p); // increases listToCheck.size()!!!
}
}
}
Not really. Both cases are comparing the value at two memory addresses with every iteration, except you are doing unnecessary assigning when you use a len variable. The performance difference is probably very small, and the first line is more readable, so I would use the first way as it is more readable. If you want to be even more readable and efficient, use a for-each loop if you are just going to do a linear iteration through your array. For-each loops look work like this:
int [] myArray = {1,2,3};
for(int i:myArray){
System.out.print(i);
}
will print:
1
2
3
as i is set to each element of the array. The for each loop can be used for many objects, and is a nice feature to learn.
Here is a guide explaining it.
https://www.udemy.com/blog/for-each-loop-java/
I am trying to learn recursion in Java and have an array that takes in continuous input until the Scanner reads in a 0.
From there I have a method that (attempts) to calculate the number of positive integers in the array using recursion. This is the first recursive function I have ever written and I keep getting a stackoverflow error.
I have read tutorials and I still can't wrap my head around the basic understanding of recursion.
public class reuncF {
private static int start = 0;
private static int end = 98;
public static void main(String[] args) {
input = input.nextDouble();
list[i] = numInput;
computeSumPositive(numList, count);
}
}
return positives += solve(numbers, count++);
}
}
You forgot to stop your recursion!
There has to be some case where computeSumPositive returns without calling itself again. Otherwise it'll just keep going forever, never getting back to you.
If you did it with a loop, the loop would look like this:
int positives = 0;
for (int i = 0; i < numList.length; ++i) {
if (numList[i] > 0) {
positives++;
}
}
To do that recursively, you just find out what are the variables used in the loop. They are i, numList and positives.
computeSumPositive(int i, double[] numList, int positives)
Then we take a look at what the loop does. First, it checks whether we went too far,
so our recursive function should do that too. It'll have to return instead of just falling through like the loop does. And obviously, it must return the result:
{
if (! (i < numList.length))
return positives;
The loop then does the test and maybe increments positives, so the recursive function should also do that:
if (numList[i] > 0) {
positives++;
}
At the end of the loop, i is updated:
i++;
The loop just starts over, but the recursive function will have to call itself. Of course, we want it to use the new value of i and positives, but fortunately we updated those, so now we can just do:
return computeSumPositives (i, numList, positives);
}
The tricky bit is that the values i, numList, and are local to each call. Each invocation of computeSumPositives can see only the arguments it were given. If it changes them, none of the other invocation can see that change.
EDIT: So if we, for reasons we can only speculate about, wanted desperately for computeSumPositive to take only 2 parameters, we would have to "split up" positives across each invocation. Each invocation knows whether or not its number was positive or not; all we have to do is add them. Then it looks like this:
computeSumPositive(int i, double[] numList)
{
if (! (i < numList.length))
return 0; // I didn't find any at index i
if (numList[i] > 0) {
// Theres one I found + however many my later
// invocations will find.
return 1 + computeSumPositive (i+1, numList);
} else {
// I didn't find any, but my later invocations might.
return computeSumPositive (i+1, numList);
}
}
I find it helpful, when dealing with recursion, to figure out the termination case first.
It looks like you are treating 'count' as an index. So you could check if your at the last index in the array, if so and if the value is positive return a 1, if the value is non-positive return a 0 - dont recurse anymore.
If your not at the last index, and the value is positive return a 1 + the recursive function call, or if the value is non-positive just continue to recurse.
This will still cause a stack overflow for large arrays.
The value of count++ is the same as the value of count; the program uses the value and then increments it. But the result is that computeSumPositive keeps calling itself with the same value of count, which leads to infinite recursion. Note that each time computeSumPositive calls another computeSumPositive, each call has its own copy of the parameters (like count) and the local variables; so incrementing one computeSumPositive's copy of count has no effect on the value of count used by other recursive calls.
Change count++ to count + 1, and also add a way to halt the recursion. (At some point, you will be calling computeSumPositive to look at zero integers, and at that point, it should just return 0 and not call itself. You need to think about: how do you test whether you've reached that point?)
I have been debugging my implementation of Game of Life, and my main problem looks like its coming from how I use arrays.
public boolean[][] oldState;
public boolean[][] newState;
private boolean gameState = true;
public LifeBoard(Seed seed) {
oldState = seed.getSeed();
newState = new boolean[oldState.length][oldState[0].length];
run();
}
public void run() {
//debug code to run for x generations
for (int i = 0; i < 5; i++) {
BoardPrinter.print(oldState);
evaluateCells();
oldState = newState;
}
BoardPrinter.print(oldState);
System.out.println("game over");
}
the boolean[][] from Seed is a 5x5 grid, all false (dead) except the 3 horizontal middle cells in the middle row
00000
00000
0+++0
00000
00000
evaluateCells() looks at each cell in the grid, looks at the 8 cells around it, counts them, and based on the number of neighbors it writes a new value to newState.
What should happen: use oldState to calculate newState, copy newState to oldState, then go back through newState, writing each cell again based on the new oldState.
What really happens: the first generation works correctly, but after that the results are increasingly weird, it evaluates cells to be false that I know to be true, etc. The problem seems to be in the way I am copying the arrays.
If I initialize a 3rd blank array blankState[][] = new boolean[5][5];
and during the loop in run say:
public void run() {
//debug code to run for x generations
for (int i = 0; i < 5; i++) {
BoardPrinter.print(oldState);
evaluateCells();
oldState = newState;
newState = blankState;
}
BoardPrinter.print(oldState);
System.out.println("game over");
}
...then the game works correctly for an additional 1 generation, then the weird garbage returns.
I have 2 questions: first, it looks like I have to use System.arraycopy(), but unless someone tells me about a version for multidimensional arrays, I will have to write a simple loop.
My real question: why do you have to use this special System method to copy an array? Why can't you use the = operator?
EDIT: the conceptual answer is accepted below. Here is the code that solved the implementation problem:
for (int n = 0; n < oldState.length; n++) {
System.arraycopy(newState[n], 0, oldState[n], 0, oldState.length);
}
for (int t = 0; t < newState.length; t++) {
System.arraycopy(blankState[t], 0, newState[t], 0, newState.length);
}
Also for the record, System.arraycopy(boolean[][], 0, boolean[][], 0, boolean.length); did not work correctly, you have to iterate through each line.
My real question: why do you have to use this special System method to copy an array? Why can't you use the = operator?
This is actually an important Java lesson, so pay attention. Are you paying attention? Good. This will be important in the future.
Now, this applies for all objects in Java, as arrays are objects. If you use = then you only set the reference, and encounter all kinds of fun as seen here. Namely, if I have a simple class with a getter and setter called TestClass with a public int test, then the following code will work:
TestClass t=new TestClass();
t.test=1;
TestClass t1=t;
t1.test=6;
System.out.println(t.test); //prints 6.
Now, why? Because the references t and t1 point to the same object on the heap. And this holds for arrays as well. To get copies, you need to perform tasks that are object-specific. Some let you call clone() directly(Cloneable interface), some let you pass another instance into the constructor to get a new instance(Like the ArrayList constructor), and some use utility methods, like arrays here.
evaluateCells() looks at each cell in the grid, looks at the 8 cells
around it, counts them, and based on the number of neighbors it writes
a new value to newState.
What should happen: use oldState to calculate newState, copy newState
to oldState, then go back through newState, writing each cell again
based on the new oldState.
What really happens: the first generation works correctly, but after
that the results are increasingly weird, it evaluates cells to be
false that I know to be true, etc. The problem seems to be in the way
I am copying the arrays.
Without seeing your bit shifting code, I'd bet this is caused by a higher level problem. Most likely your bit shifting algorithm has a bug somewhere.
Have you stepped through your code with Eclipse's debugger? If not, read this tutorial and try a few different seeds. This will tell you where, if anywhere, in your algorithm the bit shift error occurs.
http://www.vogella.com/articles/EclipseDebugging/article.html