Java code containing ! In for loop - java

How does ! big in the for loop affects the program.Is there any checking done between i and big?
public int numberOfMoves(int size) {
int power=2;
int[] moves = new int[105];
int pocet = 0;
boolean big=false;
for (int i=1;i<105&&!big;i++) {
int num=1;
for (int j=0;j<power;j++) num*=i;
if (num>size) big=true; else {
moves[pocet]=num;
pocet++;
}
}
}

! is a negation operator, this means that !true == false and !false == true. In this case, the outer loop condition is "Loop while i<105 and big is false"

the ! operator is checking to see whether big is false. So as long big is false it will run.

Related

Boolean use in an if statement

public static int search(int[] a, int target)
{
int i=0;
boolean found = false;
while((i<a.length) && ! found)
{
if (a[i] == target)
{
found = true;
}
else i++;
}
if (found) return i;
else return -1;
}
I dont understand the if statement part. So how i am reading it in my head is found is set to false. If not found...so if not false (since found = false), do whatever. So basically im reading it as a double negative and seeing if (true) dow whatever. But it doesnt make sense. I know its not an inifite loop and it runs fine but I dont get the logic, it must not be a double negative. Thanks!
EDIT:
So i get that we could just return i, much easier yes I agree. I just am having trouble with the logic of the boolean value being used in the loop with the not "!" symbol.
Basically if i wrote this i would say (ignoring everything else)
found = true //found is true to begin with
while (!found) //while not true
continue to next index //continue until ....actually i'm getting very confused now because to break the loop we would continue until found is false which logically is backwards
EDIT: Thank you everyone for your comments!! It all helped me understand it!
public static int search(int[] a, int target)
{
for (int i = 0; i < a.length; i++){
if (a[i] == target) return a[i]; // or i if you want to get ingex of searched element
}
return -1;
}
The ! operator inverts the following logical statement (logical not gate).
Because !false is true, it means it is not a double negative.
!found means the same thing that it means in English, i.e. "not found". The entire condition with i<a.length reads "while i is a valid index and [target is] not found", which is pretty close, given that you know that "not found" refers to target
You can simplify this loop to avoid Boolean variable:
while(i < a.length) {
if (a[i] == target) {
return i;
}
i++;
}
return -1;
Do you think it is easier?
public static int search(int[] a, int target) {
for (int i = 0; i < a.length; i++) {
if (a[i] == target) {
return i;
}
}
return -1;
}
Let me break it down into a few parts for you:
while((i<a.length) && ! found)
So you start with false. As !false evaluates to true, you continue the loop until found is true which will make the whole condition false, causing you to break the loop.
i<a.length: while i<length returns true, continue the loop.
You basically want found to be false and i<length for the loop to continue. If any of the condition isn't met, you break the loop (check out the &&).
if (a[i] == target) found = true;
else i++;
This is simple: if the number is found, make the found boolean true. This will cause the next iteration condition to evaluate as false, causing the loop to break.
The code loops over the array of ints while found is false.
During the loop it compares the current array value in a (a[i]) to the target, If the values are the same, it sets found to be true.
Thus after the loop it checks if found is true, and if it is it returns i, the index of the last comparison value.
At the start of the loop found is false, so the while loop will start. Once a value is found, found is set to true and the loop stops.
I would rewrite the loop however:
public static int search( int[] a, int target)
{
int foundIdx = -1;
for( int i = 0; i < a.length && foundIdx < 0; i++ )
{
if( a[i] == target )
{
foundIdx = i;
break;
}
}
return foundIdx;
}
So, I think your doubt is on the while statement, but I'll put some comments on all the code to try to explain what it does:
public static int search(int[] a, int target)
{
int i=0;
boolean found = false;
// While i index is less than the array length AND item hasn't been found (negation of the found variable), keep iterating on the loop. If not (if any of this two conditions aren't met), continue.
while((i<a.length) && ! found)
{
/* If the targeted item has been found, set found boolean to true, so this loop will stop before next iteration
*/
if (a[i] == target)
{
found = true;
}
// If targeted item is not this one, increase the index for next iteration
else i++;
}
/* This condition only will be met if we exit the loop because we found the target. In that case, we will return the index in the array of that index. If we "finished" the array without finding it, we will return -1, meaning "it wasn't found".
*/
if (found) return i;
else return -1;
}
Set the boolean found = false; because you have not found what you're looking for yet, then while (i<a.length) and ! found means that if you have not reached the end of the array and you have not found what you're looking for do
{
if (a[i] == target)
{
found = true;
}
else i++;
}
If you found it change the variable found to true which with the negation operator ! will be changed to false and the && will take you out of the while loop since one of the 2 conditions is not true any more.
In other words if found is false then in the loop is true because you have ! (not) found it. And if found is true then in the loop is false because you have found it.
What you think about using IntStream ?
public static int search(int[] a, int target) {
final OptionalInt index = IntStream.range(0, a.length).filter(i -> a[i] == target).findFirst();
return index.isPresent() ? index.getAsInt() : -1;
}

Not changing boolean

I have a method for testing if a number is a prime number. I have tested the method with 8445, which is not prime because it can be divided by 3. Although the for loop has the 3 as you can see in console, it prints true. That println is in the main method of which I did not take a picture.
public boolean Primzahlerkennen(int i)
{
boolean bool = true;
for (int a = 2; a < i; a ++) {
if (i % a == 0)
bool = false;
else
a++;
if (a==3){
System.out.println("here "+a);
System.out.println(8445%3);
}
}
return bool;
}
Why doesn't the value change to false although 8445 % 3 == 0?
The issue is that you increment a twice, once in the for statement and once in the body of the loop itself.
This causes your loop to skip some divisors (three being one of them).
Further suggestions:
Give your boolean variable a name that reflects its purpose (and not bool).
You don't need to check even divisors other than 2 since none of them are prime.
You can stop the loop at sqrt(i) (figuring out why this is correct is left as an exercise for the reader).

Comparing each element in of two arrays

Here's my problem:
Write a method called allLess that accepts two arrays of integers and returns true if each element in the first array is less than the element at the same index in the second array. Your method should return false if the arrays are not the same length.
Here is my test data:
int[] arr1 = {1,2,4};
int[] arr2 = {3};
int[] arr3 = {5,4,6};
int[] arr4 = {2,2,7};
int[] arr5 = {2,3,6,8};
System.out.println(allLess(arr1,arr2)); //should print false
System.out.println(allLess(arr1,arr3)); //should print true
System.out.println(allLess(arr1,arr4)); //should print false
This is the code I have so far:
public static boolean allLess(int[] a, int[] b){
int len1=a.length;
int len2=b.length;
if(len1==len2){
for(int i=0; i<len1;i++)
if(a[i]<b[i])
return true;
}
else if(len1 !=len2)
return false;
return false;
}
However, when I try System.out.println(allLess(arr1,arr4)); it's printing true. How do I fix this?
The crux: you should scan until you find a mismatch. You're currently only looking for the first happy case.
The main part that you need to change is your conditional - flip its condition.
if(a[i] >= b[i]) {
return false;
}
Be sure to change your last return to true as you've exhausted all negative conditions, and you're pretty much good to go.
There's more cleanup that should be done here, since we're looking at it.
First, use braces everywhere. Do so and your code will be a fair bit easier to follow. You also won't run into bugs if you suddenly discover you need to add more to a conditional block without braces.
Next, you don't need to declare more variables for the length of the arrays - you only care about them in two spots. Just reference a.length and b.length directly as it's not a method call; it's a field, which costs nothing to access.
Third, your else if condition is redundant; it should be an else. Either the lengths of the arrays are equal or they're not.
Here's what it might look like overall:
public static boolean allLess(int[] a, int[] b) {
if (a.length == b.length) {
for (int i = 0; i < a.length; i++) {
if (a[i] >= b[i]) {
return false;
}
}
} else {
return false;
}
return true;
}
Simplifications to this basic form exist.
If you were interested in a Java 8-centric approach, then you could consider this methodology with streams. Essentially, we want to scan all of your elements, and reject the entire statement if the length of the arrays are not equal AND if the value in ai is not equal to bi.
public static boolean allLess(int[] a, int[] b) {
return a.length == b.length && IntStream.range(0, a.length)
.allMatch(i -> a[i] < b[i]);
}
The if statement is returning early, you need to invert the logic and return:
if(a[i]>=b[i])
return false;
This code only compares the first two elements of the arrays. You could instead try the following:
public static boolean allLess(int[] a, int[] b){
int len1=a.length;
int len2=b.length;
if(len1==len2){
for(int i=0; i<len1;i++)
if(!(a[i]<b[i]))
return false;
}
else if(len1 !=len2)
return false;
return true;
}

Some of my prime numbers are coming up as not prime [duplicate]

This question already has answers here:
.class expected error in my method and sometimes missing return statement error
(3 answers)
Closed 9 years ago.
Im not too sure whats wrong with my code, it seems like most things are coming up prime.
public static char isPrime(int x)
{
char result = 'r';
for(int y=2;y<x;y++)
{
if(x%y==0)
result = 't';
else
result = 'f';
}
return result;
}
You are always going to the end of the loop so the result will be for x-1.
You need to start with result = 't' and break out of the loop for false values.
When you just toggle like that, you throw away all previous results.
Assume it is prime until you find a composite number
public static char isPrime(int x)
{
char result = 't';
for(int y=2;y<x;y++)
{
if(x%y==0)
{
result = 'f';
break;
}
}
return result;
}
public static char isPrime(int x)
{
char result = 't';
for(int y=2;y<x;y++)
{
if(x%y==0) {
result = 'f';
break;
}
}
return result;
}
Try this:
public static boolean isPrime(int x) {
for (int y = 2; y*y <= x; y++) {
if (x % y == 0)
return false;
}
return true;
}
What was changed:
You should use boolean values to indicate that a condition is true or false, instead of the characters 't' and 'f'.
The biggest problem in your code was that, as soon as you found a divisor for your number (if (x%y==0)) you must break out of the loop, because at this point we're sure that the number is not prime, so there's no point in continuing
Only if no divisors were found, we can return true at the end, outside of the loop
You should break or return after you find out that your number is not a prime, simple as that. Additionally it seems that you return t when the number is NOT a prime.
Please use boolean and provide an Junit testcase, so we know what you exactly expect.
public static boolean isPrime(int x)
{
for(int y=2;y<x;y++)
{
if(x%y==0)
return false;
}
return true;
}
Your true and false are reversed, if its exactly divisable by something its not prime
Also, you're overwriting all your old data on each run through the loop, as soon as anything is exactly divisible then its not prime, return false at that point
Also, have you considered using the booleans true and false?
You method is not resolving prime numbers. A number is a prime if it can only be divided by one or itself.
If I input 17 into your method, for example, the result will be set to 'f' when y == 16, and that will be the returned result. However, 17 is a prime number.
You should instead try something like
for (int i = 2; i < x; i++) {
if (x % y == 0) return false;
}
return true;

Can anyone see where the infinite loop in my program is?

The purpose of this program is to find the smallest number evenly divisible by all integers 1 through 20. I know it could be made more efficient, but I'm not interested in optimizing it right now. When I execute the program, it seems to hang forever, which leads me to believe that there's an infinite loop somewhere. I can't seem to find it though. I'm not sure what part of the code is causing the problem and it's relatively concise, so I'll post it all here.
public class Problem5{
public static void main(String[]args){
boolean notFound = true;
while(notFound){
int n = 20;
if(testDivide(n)){
System.out.println(n);
notFound = false;
}
else
n++;
}
}
private static boolean testDivide(int target){
for(int i = 20; i > 0; i--){
if(target % i != 0)
return false;
}
return true;
}
}
If anyone can help me out with this, I'd appreciate it a lot.
Additional Information: The program also never outputs any numbers, which leads me to believe that if(testDivide(n)) is never evaluating to true.
You are initializing the value of n inside your while loop to 20, since n is always 20 for testDivide(20), which will always return false since 20 % 19 != 0 returns false. Hence remove int n = 20 from your while loop.
boolean notFound = true;
while(notFound){
int n = 20;
should be
boolean notFound = true;
int n = 20;
while(notFound) {
your for loop makes sure you return false, and then your while loop always sets i to 20 this is your infinite loop.
See the while loop:
while(notFound){
int n = 20;
if(testDivide(n)){
System.out.println(n);
notFound = false;
}
else
n++;
}
When the while loop is executed first, the value of n is set to 20.
the test divide returns false.
The value of n is decremented to 19.
The loop executes again
The value of of n is reinitialized to 20.
This is the problem initialize n outside the while loop.

Categories

Resources