Using a break to get out of an enhanced for loop - java

Hi everyone I was asked to write the following method for homework and I need some clarification. Basically I want to know if the Comparable item given as a parameter is part of the comparableList array. Assuming the array is sorted, I was told to stop checking the array if the comparableList has the item in it or if item is smaller than the following item of the array. I used break but I am not sure if break will get me out of the enhanced for loop to avoid checking the whole array if any of the conditions are true. I want to make sure that if there are 50,000 items in the array and I find the item at position 5 to stop checking the rest of the array. I have never used break before so I am not sure if it will get me out of the for loop.
public boolean contains(Comparable item) {
Comparable[] comparableList= getStore();
boolean isThere = false;
for(Comparable p : comparableList)
{
if(item.compareTo(p)==0)
{
isThere = true;
break;
}
if(item.compareTo(p)<0)
{
break;
}
}
return isThere;
}

The break will break out of any loop, including the enhanced one. Your solution will work.
However, since you are returning as soon as you find your item, you could change the loop to return as soon as the item is found, or as soon as you know that you are not going to find it:
Comparable[] comparableList= getStore();
for(Comparable p : comparableList) {
if(item.compareTo(p)==0) {
return true;
}
if(item.compareTo(p)<0) {
return false;
}
}
return false;
Moreover, since the array is sorted, linear search is not your best strategy: implementing Binary Search could make your algorithm significantly faster.

If you want to know the best way of stopping once it's found, just do this:
public boolean contains(Comparable item) {
Comparable[] comparableList= getStore();
for(Comparable p : comparableList)
{
if(item.compareTo(p)==0)
{
return true;
}
if(item.compareTo(p)<0)
{
return false;
}
}
return false;
}

Related

Trying to create a RetainAll method

I am trying to create a RetainAll method and all after scouring the forums I have found nothing that helps in my specific case. The issue I am having is that when running my program instead of retaining all the elements form a specified list and deleting all others it instead keeps the last element form the initial list.
public default boolean retainAll(Collection<?> c) {
boolean modified=false;
int index =0;
for(Object e : this) {
if(c.contains(e)==true) {
}
else if(c.contains(e)==false) {
index=this.indexOf(e);
this.remove(index);
modified = true;
}
}
return modified;
}
public default boolean remove(Object e) {
if (indexOf(e) >= 0) {
remove(indexOf(e));
return true;
}
else
return false;
}
I am just not understanding how to remove the last element.
You're modifying the collection as you iterate over it. That is generally a recipe for unhappiness.
For the standard collections, the safe way is to use an explicit iterator, and use the iterator's 'remove' method to remove the most recently returned entry.
If this is your own collection implementation you should make sure that model works for you too.

Q: How to break a for loop inside a method?

So I'm trying to find whether array a is a subset of array b, and my code is as follows :`
public class subset {
public static boolean subset(int[]a, int[] b) {
for(int i=0;i<a.length;i++){
for(int j=0;i<a.length;j++){
if(a[i]==b[j]){
return true;
break;
}else{
return false;
}
}
}
}
public static void main(String[]args){
int[] a = {1,2,6};
int[] b = {1,2,4,3,7,4,8,5};
if (subset(a,b))
System.out.println("Array 1 is contained in Array 2");
else
System.out.println("Array 1 is not contained in Array 2");
}
}
And I am getting the following errors: unreachable statement and missing return statement.
What I want to do is that when the if condition is true it stops the inner for loop and carries on with the outer for loop.
Thanks in advance
2 things need to be fixed. You need to remove break, and add a return false at the end.
public static boolean subset(int[]a, int[] b) {
for(int i=0;i<a.length;i++){
for(int j=0;i<a.length;j++){
if(a[i]==b[j]){
return true;
//break; remove this
}else{
return false;
}
}
}
return false; //add this
}
Also, you could simplify it a bit, by doing this, instead of the if..else
return a[i]==b[j];
First problem is this:
return true;
break;}
the second line will never be executed because the first one terminates the method execution. Decide which line you want here: return a value or jump out of the inner loop (neither I presume, this branch should be empty, see below).
The second problem is that when you pass in an empty array the loops are not executed and the method does not have a value to return. Here simply add a "return true" (or false, quite arbitrary here) at the end of the method.
You probably can simplify the loop body in this way:
if(a[i]!=b[j]){
return false;
}

Stop peeking at empty stack

I'm checking that a stack is sorted by popping it and comparing the pop to the peek. If the pop is greater than the peek, we know those two elements are in order. I run this loop as long as the stack isn't empty.
The problem I'm running into is with the final element of the stack. I do my final pop, and but it tries to peek at an empty stack to make sure it's in order. Since there is nothing there, I get a runtime error.
public static boolean isSorted(Stack<Integer> s){
boolean result = true;
while(!s.empty()){
if(s.pop() < s.peek()){
result = false;
}
}
return result;
}
I'm trying to do this exclusively with Stack, so using only push pop and peek. Nothing from an ArrayList. How can I fix this problem, while still checking every element?
I've tried storing pop in a temporary variable, but that fixed nothing. Not sure what I was hoping for
The problem is that you need two items, but empty() checks for just one item. Once you call pop(), you need to do another empty() call prior to executing a peek():
while(!s.empty()){
// We know we have one element available; store it in "top"
Integer top = s.pop();
// If the next element is not available, exit
if (s.empty()) {
break;
}
if(top < s.peek()){
// Once result is set to "false", it never becomes "true"
// so we might as well return now:
return false;
}
}
return true;
It has to, as pop removes the last element and peek throws EmptyStackException if the stack is empty
public static boolean isSorted(Stack<Integer> s){
boolean result = true;
while(!s.empty()){
if(s.size() == 1)
return result;
if(s.pop() < s.peek()){
result = false;
}
}
return result;
}
One way to do it, is to check the size explicitly:
while(s.size() > 1){ // ok, we have enough elements in the stack
if (s.pop() < s.peek()) {
result = false;
break; // no need to proceed, we already know it's not sorted.
}
}

DFS tree traversal function modification

Please find below my implementation for DFS.
protected void DFS(String search) {
for(Tree<T> child : leafs) {
if(child.value.equals(search))
return;
else
child.DFS(search);
System.out.println(child.value);
}
}
The objective is to stop traversal on finding the node whose value is in the variable search. However, the above function goes on traversing the tree even beyond the declared search node. Could someone help me modify the above function?
Thank you.
Edit 1
protected boolean DFS(String anaphorKey) {
boolean found = false;
for(Tree<T> child : leafs) {
if(child.head.equals(anaphorKey))
return true;
found = child.DFS(anaphorKey);
if(found == true)
break;
System.out.println(child.head);
//System.out.println("anaphorKey: "+anaphorKey);
}
return found;
}
Tried implementing the given answer suggestion (#SJuan76). The implementation above isn't working as desired. Could you point me to the place where code is not as per the logic suggested?
rookie, might I suggest an implementation using the classic for-loop (as opposed to the enhanced for-loop being used now) which allows integration of your stop-condition a bit better, something like:
protected boolean DFS(String key) {
boolean found = false;
for(int i = 0; i < leafs.size() && !found; i++) {
Tree<T> child = leafs.get(i);
if(child.head.equals(key))
found = true;
else
found = child.DFS(key);
}
return found;
}
So as soon as your found condition is hit, the 'found' becomes true and your loop stops.
What you may have forgotten is the "found = child.DFS(key)" portion of the recursion, where you need to remember the result of your recursive calls so ALL your for-loops on up the chain all break as soon as you return.
Hope that helps.
Option A (Nice): the function returns a value, when the node is found it returns a different value that if the node was not found. When you call to method, if you get the found value you stop the loop and return the found value too.
Option B (Ugly): When found, thow an Exception (better if it is your own implementation of it). Don't forget to catch it.
Option C (Uglier): The same with global (static) variables.
UPDATE 1:
It looks like your method should run ok now, can you check (System.out.println) if your value is ever found?
In a more personal opinion, I would find
protected boolean DFS(String anaphorKey) {
for(Tree<T> child : leafs) {
if(child.head.equals(anaphorKey))
return true;
if(child.DFS(anaphorKey)) // No need to store value. No need to check == true (it is implicit)
return true; // If we are in this line the value was found, always return true
System.out.println(child.head);
//System.out.println("anaphorKey: "+anaphorKey);
}
return false; // If the method did not exit previously it was because the value was not found, so in this line always return false
}
more readable (but it should work exactly as your implementation)

Linear array search

I'm pretty new to java and I'm trying to learn so I'm just wondering how I could preform a linear search through my array.
This is what I've done so far but it doesn't work.
public boolean contains(Object elem)
{
boolean result = false;
for(int i=0;i<this.vector.length;i++)
if(elem.equals(this.vector[i]))
result=true;
else
result=false;
return result;
}
public int indexOf(V elem)
{
int pos = 0;
for(int i=0;i<this.vector.length;i++)
if(this.vector[i].equals(elem))
pos=i;
else
pos= -1;
return pos;
}
Your contains() function only returns true if the passed elem is the last item in the array. If you find it, you should return true immediately.
Your indexOf() method suffers from the same issue.
You're missing a break after you've found the element.
Oneliner:
Arrays.asList(vector).indexOf(elem);
It just creates and deletes one more object (ArrayList) in the memory. Should not be a problem in the most of situations.
You need to break your loop when you find your match.
There are a few problems with that code: in both methods, you always search through the entire array, even if you have found the element already. In both methods, this is the source of a bug (and less importantly: it is not as efficient as it could be).
for(int i=0;i<this.vector.length;i++)
if(elem.equals(this.vector[i]))
return true;
return false;
(and similar for the other method) might be a better implementation.

Categories