While I am implementing Selection sort method and executing it, some of elements are sorted while other are not. I checked over the internet about a correct implementation but I didn't find any difference except an extra opening and closing braces.
Here is my code:
public void selectionSort()
{
for(int i = 0;i<=arrSize;i++)
{
int min = i ;
for(int j = i+1;j<=arrSize;j++)
{
if(theArray[j]<theArray[min])
min = j;
swap(min,i);
}
}
}
And here is what I found on the internet:
public void SelectionSort()
{
for(int i = 0;i<=arrSize;i++)
{
int min = i ;
for(int j=i+1;j<=arrSize;j++)
{
if(theArray[j]<theArray[min])
{
min = j ;
swap(min,i);
}
}
}
}
I have tried to track where the error is but I failed so I decided to ask here about this logical error, I hope you to answer the question and explain how braces can affect the output of code in this particular case.
if(theArray[j]<theArray[min])
min = j;
swap(min,i);
and this
if(theArray[j]<theArray[min])
{
min = j ;
swap(min,i);
}
are two different codes.
in first code you swap elements EVERYTIME
in second code you swap elements only if the if statment is true.
The braces limit the if condition actions. With no baces after the if condition, only one expression will be run conditionally and the swap in the second line after the if will always be executed.
Search more info about the scope of if else expressions limited in Java by braces.
i am trying to learn java myself
You should really get a book about java basics and read though it.
i didn't find any difference except an extra opening and closing braces.
But they make the difference:
Without the braces: if the condition in the if statement is not matched the if skips the next statement only.
In Java the curly braces create so called blocks. In conjuncton with the if statement such a block as a hole is the next statement.
If there are no brackets then the compiler adds internally a bracket only for the next line. So,
if(theArray[j]<theArray[min])
min = j;
swap(min,i);
is similar to
if(theArray[j]<theArray[min])
{
min = j;
}
swap(min,i);
That's why you are getting the wrong output.
See
for(int j = i+1;j<=arrSize;j++)
{
if(theArray[j]<theArray[min])
min = j;
swap(min,i);
}
Above will execute swap method in every iteration of for loop. Because its in for loop block.
And,
for(int j=i+1;j<=arrSize;j++)
{
if(theArray[j]<theArray[min])
{
min = j ;
swap(min,i);
}
}
Above will execute swap method only when if condition satisfied.
Loops, if or any block will consider statements inside braces. If you don't use braces then it will consider only next single statement in block.
Related
In this class, I defined a constructor that initializes an array and fill it with Point2D.Double. I want to define a toString method that outputs the Point2D.Double in the array. So inside the toString method, I make a for loop that returns every Point2D.Double in the array. The problem is, I don't know why Eclipse tells me that the update in the for statement is dead code.
import java.awt.geom.Point2D;
public class SimplePolygon {
public int n; // number of vertices of the polygon
public Point2D.Double[] vertices; // vertices[0..n-1] around the polygon
// boundary
public SimplePolygon(int size) {
n = size;
vertices = new Point2D.Double[n]; // creates array with n size. Elements are doubles.
for(int i = 0; i < n; i++)
{
Point2D.Double point = new Point2D.Double(Math.random() * 6, Math.random() * 6);
vertices[i] = point;
}
}
public String toString() {
for(int i = 0 ; i < n ; i++)
{
return "" + vertices[i];
}
return "";
}
I too was puzzled by this. (And the other answers!) So I cut-and-pasted it into Eclipse to see what it actually says.
And what Eclipse is actually says is that i++ is unreachable in this line.
for(int i = 0 ; i < n ; i++)
And in fact, that is correct! If you ever enter the loop body, the body will unconditionally return. Hence the i++ can never be executed.
Note also that this is a warning not an error. This code is not invalid according to the JLS rules about unreachability.
You are right to be puzzled by the other explanations. The final return statement is reachable. Consider the case where the class is instantiated with a negative value for n (or size). In that case, the for loop body will never be executed, and control will go to the final return.
However, their suggestions as to how to fix the problem are correct. You should not have a return in the loop body.
The problem is because of the return statement in the for loop. Remember, whenever you use return, you immediately end the method and stop running any code. That means that your toString method will loop exactly only once, returning only vertices[0]. The second return below the loop never has a chance to execute, so is considered dead code.
This is actually incorrect! See Stephan's answer for a better/accurate explanation of what's going on.
Regardless, you still need to fix your code. Instead of returning something inside the loop, you probably want to combine the values and return them all at once at the very end. An easy way to do this might be:
public String toString() {
String output = "";
for(int i = 0 ; i < n ; i++)
{
output += vertices[i] + " ";
}
return output;
}
Now, instead of returning immediately, we're accumulating values in the loop and returning at the very end.
(Note that the code here isn't very efficient -- you'd probably want to use something like String.join or StringBuilder instead, but if you're a beginner, this works for now)
I'm working on an encryption assignment for my first CS class, and I'm trying to make this code work... here's what I've got.
public static void findE(int phiPQ) {
int e = 0;
for(e > 2; e < (phiPQ - 1);) {
int larger = phiPQ;
int smaller = e;
int r = 1;
r = larger / smaller;
larger = smaller;
smaller = r;
if(larger == 1) {
break;
}
return;
}
Now the issue I'm having is that when I try to do "e > 2" in the for loop it does not work, and says that the assignment operator is invalid. The assignment says that I'm supposed to use a for loop from e > 2 to e < (phiPQ - 1). How is this possible without something like a while loop? I tried that as well and couldn't get the return statement to work. Please help!
Someone has "fixed" some of the issues discussed below. YMMV.
There are several critical problems with the code. The combination of syntax and/or semantic errors may compound upon each other. First start by fixing the blatant syntax errors.
1. The for syntax is wrong.
The first "part" of a for loop statement must be an initialization statement (read: "assignment"). It cannot be an arbitrary expression. The syntax is for(initialization; termination; increment) statement - see the link for more details.
I expect the code should be:
for(/* At the start, LET e = 2 */
e = 2 ;
/* Terminate when this is false. */
e < (phiPQ - 1) ;
/* no increment */) ..
Or:
for(e = 2; e < (phiPQ - 1) ;) ..
(Or, assign 2 to e above the for-loop and provide an empty initialization statement.)
2. As identified by a comment is the code is equivalent to:
// This is a loop with AN EMPTY STATEMENT FOR A BODY due to the
// immediately trailing semicolon.
// Even when this loop is corrected per above, the condition will never
// change state due to lack of increment and it will "loop forever".
for(e > 2; e < (phiPQ - 1);) ;
// This is a new block, that does NOT BELONG to the loop above.
{
int larger = phiPQ;
int smaller = e;
int r = 1;
r = larger / smaller;
larger = smaller;
smaller = r;
}
To fix this, remove the ; immediately following the for statement.
3. The loop never changes state.
The termination condition is dependent upon e and phiPQ. However, these variables are never changed and so the loop will either never loop or never terminate normally.
Review the loop termination conditions and state advancement.
4. break is used outside of the for statement.
While #3 asserts that the code never terminates, it may be the case that the if statement containing the break (which is incorrectly located outside of a looping construct and will result in a syntax error) is meant to terminate the loop. If this is the case, then it should be inside the loop body.
How about:
for (int e = 0; e > 2 && e < (phiPQ - 1);)
{
// your code
}
For loop :
for(int e = 3; e < (phiPQ - 1); e++){
}
You are receiving this error because the first expression in a for-loop is used for initialisation. The second expression is then your termination condition; when the termination condition evaluates to false, the loop will end. e.g.
for (int i = 0; i < numIterations; i++) {}
This loop will iterate through the body numIterations times.
You will therefore want to more fully define the iteration space of your loop in the second expression, or perform assignment of e through the first expression.
For more information, refer to the Javadoc for for-loops.
Is there ever a situation where you must use a do while loop? Is it an accepted practice? It seems like it is equivalent to a plain while loop except that its first iteration happens before checking the conditional, if that is even true.
int i = 3;
while ( i > 0 ) { // runs 3 times
i--;
}
vs
int j = 3;
do {
j --;
} while ( j > 0 ); // runs 3 times
The same?
EDIT: I have seen the java doc, but
the example in the java docs doesn't look like it requires that the particular routine inside of the do while loop must be run in the do while loop instead of inside of a regular while loop!
Is there ever a situation where you must use a do while loop?
No: every do-while loop can be written as a while-loop by running the body once before the loop begins. However, there are certainly cases where it makes more sense to use the do-while construct (i.e. if you always want the loop to iterate at least once), which is why it exists in the first place.
Is it an accepted practice?
If you use it appropriately, then yes absolutely.
It seems like it is equivalent to a plain while loop except that its first iteration happens before checking the conditional, if that is even true.
That's right. You can read more about do-while in its tutorial.
This example maybe help you be clearer:
int i = 3;
System.out.print("while: ");
while (--i > 0){
System.out.print("x");
}
System.out.print("\ndo-while: ");
int j = 3;
do
{
System.out.print("x");
}while (--j > 0);
This prints
while: xx
do-while: xxx
A real time example.
There is a contest with 5 level.
In each level if you score 100 you can proceed to next level.
Less code for do while, but not for while.
boolean playContest()
{//do while
int level = 1;
int score;
do
{
score = 0;
score = play();
}while(score>99 && level++<6)
if(level>4 && score>99)
isWinner = true;
else
isWinner = false;
return isWinner;
}
boolean playContest()
{//while
int level = 1;
int score;
while(level <6)
{
score = 0;
score = play();
if(score < 100)
break;
level++;
}
if(level>4 && score>99)
isWinner = true;
else
isWinner = false;
return isWinner;
}
basic difference between while and do-while is do while will be executed at least once.
when do-while is best option?
in case when you want to execute some actions till you meet condition, of course you could achieve same thing by using while but early termination of loop with break, is nasty and ugly solution
When you want to execute the statement inside do for at least once, then you can go for it.
Directly from Docs
The difference between do-while and while is that do-while evaluates its expression at the bottom of the loop instead of the top. Therefore, the statements within the do block are always executed at least once,
do {
statement(s)
} while (expression);
No, there is no time a do-while loops is the only option, it is used for convenience when you do not want to repeat code.
i have recrusive function which works fine. The problem is it gives stackoverflow error when the number of lines are huge. I want to put it in iterative, probably using a for loop. Need some help in doing it.
private TreeSet validate(int curLine, TreeSet errorSet) {
int increment = 0;
int nextLine = 0;
if (curLine == lines.length || errorSet.size() != 0) {
return errorSet;
} else {
String line = lines[curLine];
//validation starts. After validation, line is incremented as per the requirements
increment = 1 //As per requirement. Depends on validation results of the line
if (increment > 0) {
try{
Thread.currentThread().sleep(100);
}catch(Exception ex){
System.out.println(ex);
}
nextLine = (curLine + increment);
validate(nextLine, errorSet);
}
}
return errorSet;
}
Poster's description of the method:
The method does validates textlines, these lines has instructions of how much line has to be skipped, if the line is valid. So, if the line is valid that many of lines will be skipped using the increment. if the line is not valid increment will be 0.
I'm not sure why this was ever recursive in the first place. This is perfectly suited for the use of a FOR loop. use something like so:
private TreeSet validate(int curLine, TreeSet errorSet) {
int increment = 0;
if (errorSet.size() != 0)
return errorSet;
for (int curLine = 0; curLine < lines.Length; curLine += increment)
{
// put your processing logic in here
// set the proper increment here.
}
}
If the increment is always going to be 1, then you can just use curr++ instead of curLine += increment
for(String line : lines) {
// validate line here
if(!errorSet.isEmpty()) {
break;
}
}
The solution for your problem could be simple for loop or while, with logical expression for stop condition. Typically we use for loop when we have to pass through all elements of Iterable or array. In case when we are not aware how many loops we are going to do we use a while loop. Advantage of for loop over while, is that we for free have localized variables so we ca not use them out side of the loop, therefore we reduce possibility to have some bug.
You problem is that you have to break the program on two conditions:
When errorSet is not empty.
When the array of lines have no longer items.
As contradiction, we can say that your program should continue:
Until errorSet is empty,
and until line number is smaller than array size where they are stored.
This provide us to simply expression
errorSet.isEmpty()
lineNumber < lines.length()
We can combine them using logical operator && and use as a stop rule in for loop.
for(int lineNumber= 0; errorSet.isEmpty() && lineNumber< lines.length(); lineNumber++) {
//code to operate
}
Note:
Typically for logical expression is used operator &&, that assure that every part of the logical expression is evaluated. An alternative for this is &, that in case of false do not operate longer and return false. We could be tempted to use this operator for this expression but i would be bad idea. Because when we would traversed all lines without error code will generate IndexOutOfBoundException, if we switch the places then we would not have any optimization as first expression would be evaluated same number of times.
Has anyone ever seen the following in Java?
public void methodName(){
search:
for(Type[] t : Type[] to){
do something...
}
}
Can someone point me to documentation on the use of "search:" in this context? Searching for "search:" has not been productive.
Thanks
It's a label. From §14.7 of the Java Language specification:
Statements may have label prefixes...
(Boring grammar omitted, pain to mark up)
Unlike C and C++, the Java programming language has no goto statement; identifier statement labels are used with break (§14.15) or continue (§14.16) statements appearing anywhere within the labeled statement.
One place you frequently see labels is in nested loops, where you may want to break out of both loops early:
void foo() {
int i, j;
outerLoop: // <== label
for (i = 0; i < 100; ++i) {
innerLoop: // <== another label
for (j = 0; j < 100; ++j) {
if (/*...someCondition...*/) {
break outerLoop; // <== use the label
}
}
}
}
Normally that break in the inner loop would break just the inner loop, but not the outer one. But because it's a directed break using a label, it breaks the outer loop.
This is an example of a labelled loop.
It allows you to break or continue the target loop instead of your current loop.
Outer:
for(int intOuter=0; intOuter < intArray.length ; intOuter++)
{
Inner:
for(int intInner=0; intInner < intArray[intOuter].length; intInner++)
{
if(intArray[intOuter][intInner] == 30)
{
blnFound = true;
break Outer; // this line breaks the outer loop instead of the inner loop.
}
}
}
example taken from : http://www.java-examples.com/java-break-statement-label-example
It is a Java label as defined here in JLS: http://docs.oracle.com/javase/specs/jls/se5.0/html/statements.html#78994