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;
}
Related
I am trying to solve a question in which I am given a String array of words and I have to check whether they have all same length or not. For instance if am given the array {"apple","purple","lemon"} then my method should return true, and when I am given the array {"red","blue"}, it should return false.
This is what I did so far but it is not working. I appreciate any help.
public static boolean allEqualLength(String[] myArray){
int i;
for(i=0;i<myArray.length;i++){
if(myArray[i]!=myArray[i+1])
return false;
}
return true,
}
All items having the same length is equivalent to saying all items must have the same length as the first item:
public static boolean allEqualLength(String[] myArray) {
// zero items => "all" items have same length:
if (myArray.length == 0) return true;
final int expectedLength = myArray[0].length();
for(int i = 0; i < myArray.length; ++i) {
if(myArray[i].length() != expectedLength)
return false;
}
return true,
}
But your original solution was not that far off. You just need to make sure not to exceed the array's bounds and to compare the string lengths, not the strings themselves:
public static boolean allEqualLength(String[] myArray) {
for(int i=0; i < myArray.length - 1; i++) { // -1 to not exceed bounds
if(myArray[i].length() != myArray[i+1].length()) // compare length, not memory addresses
return false;
}
return true,
}
I world do something like that:
public static boolean allEqualLength(String[] myArray) {
int strLength = myArray[0].length();
for (String str :
myArray) {
if (str.length() != strLength)
return false;
}
return true;
}
Like that you can avoid any indexing problems in your loop.
You are trying to compare the strings themselves. You should compare the length only.
myArray[i].length() != myArray[i + 1].length()
By the way, this will throw an ArrayIndexOutOfBoundsException, because you are trying to access index myArray[myArray.length]. Change the for loop to
for (int i = 0; i < myArray.length - 1; i++) {
if (myArray[i].length() != myArray[i + 1].length()) {
return false;
}
}
Also make sure you return true if the array length is 0 or 1, because the loop can't handle those.
For example you have array with length 4 , you have the positions 0,1,2,3 so in your code you run with : myArray[i]!=myArray[i+1] so on the last run you check the positions :
3 and 4 and you will get ArrayIndexOutOfBoundsException , you need to change to : length-1 on the loop condition like this :
public static boolean allEqualLength(String[] myArray){
int i;
for(i=0;i<myArray.length -1;i++){
if(myArray[i].length() != myArray[i+1].length())
return false;
}
return true,
}
If you run on myArray.length ,the positions that check :
0--1
1--2
2--3
3--4 // ERROR !!! ArrayIndexOutOfBoundsException !!
If you run on myArray.length-1 ,the positions that check :
0--1
1--2
2--3 -OK !!!
So on this way if you run the array with : myArray.length-1 , you will not get ArrayIndexOutOfBoundsException .
First things first you are not checking element lengths other issue is your for loop would try to access array index out of bounds since you have i+1, last element is already being checked that way, considering that you just need for until myArray.length - 1.
Using your code it would look something like this:
public static boolean allEqualLength(String[] myArray) {
for (int i = 0; i < myArray.length - 1; i++) {
if (myArray[i].length() != myArray[i + 1].length())
return false;
}
return true;
}
If performance is not an issue and you will not use it in 1 million strings or something, in addition to all these answers, here is an one liner:
boolean allStringsEqualLength = Stream.of(array)
.map(String::length).distinct().count() == 1;
The idea is to map each string to its length. So if distinct() stream contains only one value, that means all strings had the same length.
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;
}
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.
This is what I have so far, I managed to reach here with several hours of work. The problem with my code is that if i give it a string "abcefg" it will verify the first two characters and returns it as true. I want the code to do it for all of my characters. I thought that putting the limit as x.length() would do the thing, but for some reason, it won't work.
public static boolean ConsecutiveCheckerAscending(String x) {
x = x.toLowerCase();
for (int i = 0; i < x.length() - 1; i++) {
if ((int)x.charAt(i) + 1 != ((int)x.charAt(i + 1)))
{
return false;
}
}
return true;
}
public static boolean ConsecutiveCheckerDescending(String x) {
x = x.toLowerCase();
for (int i = 0; i < x.length() - 1; i++) {
if((int)x.charAt(i) - 1 != ((int)x.charAt(i + 1)))
{
return false;
}
}
return true;
}
You have a variety of issues here.
Firstly, you can eventually go out of bounds with the charAt(i + 1) calls (check your loop condition).
Secondly, how can you possibly return true in the body of the for-loop? You haven't checked all of the characters yet!
I think you're making this overly complicated, though. All you need to do in order to check that two contiguous (i.e. next to each other in the string) characters are consecutive is
Math.abs(s.charAt(i) - s.charAt(i + 1)) == 1
You actually don't even need a cast. What we're doing is checking that the "distance" between the two characters is 1.
Just apply that to every contiguous pair of characters in the string, and return false if it isn't satisfied somewhere along the line. If you exit the loop without ever returning false, you can return true.
You cannot know for sure if the string is consecutive until the end of the method, so you cannot return true in the middle. At most you can return false when you find that string is not consecutive.
To give more advice, what do you mean by "consecutive"? Is adgkm consecutive? Looking at the current code it would look like it; all you check is the order of the characters. Is abcdcbcd consecutive? Usually "consecutive" means there are no gaps.
In both if and else statements you having return statement, So the method will return after first check. You have to give return only for the exit condition. don't give for both if and else
Wrote it in a rush, but it'd look something like this.-
public static boolean ConsecutiveChecker(String x) {
boolean consecutive = true;
x = x.toLowerCase();
for (int i = 0; i < x.length() - 1; i ++) {
if ((int) x.charAt(i) + 1 != ((int) x.charAt(i + 1))) {
consecutive = false;
break;
}
}
return consecutive;
}
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.