Converting a do-while loop into a for loop in Java - java

So I had this while loop for a lab in my class I had to make. I then had to convert the loop to a do-while loop to see the difference in design and make sure I got the same results. Now I need to convert it into a for loop, but I don't know how to set up the for statement. Here is how it is currently:
do
{
die1Value = generator.nextInt(6) + 1;
die2Value = generator.nextInt(6) + 1;
if (die1Value == die2Value)
{
if (die1Value == 1)
{
snakeEyes += 1;
}
else if (die1Value == 2)
{
twos += 1;
}
else if (die1Value == 3)
{
threes += 1;
}
else if (die1Value == 4)
{
fours += 1;
}
else if (die1Value == 5)
{
fives += 1;
}
else if (die1Value == 6)
{
sixes += 1;
}
}
count += 1;
}while (count < NUMBER);

As others have mentioned, the problem arises that the for loop will check the condition at the beginning of the loop, but your do while loop will check the condition at the end of your loop.
All that means is that with a for loop, you are not guaranteed at least one iteration. However, with a do while loop, you are guaranteed at least one.
Assuming that's not a problem, the for loop statement could be this:
for (count = 0; count < NUMBER; count++)
count = 0 may need to be changed to count = 1 or whatever count is originally supposed to start at.
However, seeing as how count would need to be initialized for your current code, you can just omit the initialization part in your for loop like so:
for (; count < NUMBER; count++)

Make use of the Java Tutorials and Java Docs; you look to have a grip on the syntax and the meaning of each part of the loop so it shouldn't be too hard to figure out how to convert it once you read this.
(source)http://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
The for statement provides a compact way to iterate over a range of values. Programmers often refer to it as the "for loop" because of the way in which it repeatedly loops until a particular condition is satisfied. The general form of the for statement can be expressed as follows:
for (initialization; termination; increment) {
statement(s);
}
When using this version of the for statement, keep in mind that:
The initialization expression initializes the loop; it's executed once, as the loop begins.
When the termination expression evaluates to false, the loop terminates.
The increment expression is invoked after each iteration through the loop; it is perfectly acceptable for this expression to increment or decrement a value.

The do-while loop does not check the condition on the first iteration, but a for loop does. Therefore, you need to make condition in for loop always true at the first time.
Try this:
for (boolean keepWorking = true; keepWorking; keepWorking = ++count < NUMBER) {
// ...
}

Related

Method to print odd numbers between 1 and 100

I have to write a method that returns/prints the odd numbers between 1 and 100, but I have to use another method, which checks whether a given integer is odd or not:
static boolean isOdd(int c) {
boolean d;
d = c % 2 != 0;
return d;
}
I'm guessing that I have to use either a for- or while-loop (probably can be done with both?), but I think what I'm really struggling with is "connecting" both methods. So the numbers actually run through isOdd() which determines whether they are odd.
I've tried these two options so far, but they're not working.
Option 1:
static void func1() {
int number = 1;
while (number < 100 && isOdd(number)) {
System.out.println(number);
number = number + 1;
}
}
Option 2:
static void func1() {
int i;
for (i = 1; i < 100; i++) {
isOdd(i);
}
System.out.println(i);
}
Your attempt #1 is closer to your goal ;)
you are right that you can use while and for (and probably other kinds of processing multiple numbers, but that just for the sake of completeness, forget it for now)
your println (or print) should be within the loop because you want to print more than just one number.
in you current attempt #1 you end your loop with the first odd number: 1 This doesn't count up very far ;)
So you have to use an if inside your loop where you check the result of isOdd(number) and only print if it's odd.
But the loop has only the upper bound limit as condition (number < 100) as you want to check all the numbers.
Smartass hint (try it only after your program works fine): if you count up by 2 instead by 1 (number = number + 2;), your program will only need half the time - and you could even skip the isOdd check ;-)
I'm guessing that I have to use either a for- or while-loop (probably can be done with both?)
Yes. for-loops are just syntactic sugar for special while-loops:
for (init_stmt; cond; incr_stmt) body_stmt;
is equivalent to
init_stmt;
while (cond) {
body_stmt;
incr_stmt;
}
Let's first write this using a for-loop.
for-loop
for (int i = 1; i < 100; i++)
if (isOdd(i))
System.out.println(i)
Note that we can (and should!) do the declaration of i as int in the for-loop initializer.
Now, we may translate this to an equivalent while-loop:
while-loop
int i = 1;
while (i < 100) {
if (isOdd(i))
System.out.println(i);
i++;
}
Mistakes in your attempts
Attempt 1
You've mistakenly included the check in the condition (rather than using it in an if inside the loop body); the first even number (2) will cause the loop to terminate.
Attempt 2
You're not even using the return value of isOdd here. You're unconditionally printing i after the loop has terminated, which will always be 100.
The ideal implementation
Ideally, you'd not be filtering the numbers; you'd directly be incrementing by 2 to get to the next number. The following loop does the job:
for (int i = 1; i < 100; i += 2)
System.out.println(i);

Program to find Prime numbers. Chapter 2 Self test schildt java beginner's guide

In Self tests of chapter 2 Schildt's Java Beginners Guide there is an exercise to write a program that finds all of the prime numbers between 2 and 100.
The correct answer that the author gives is as follows:
class Prime {
puЬlic static void main(String args[]) {
int i, j;
boolean isprime;
for(i=2; i < 100; i++) {
isprime = true;
for (j=2; j <= i/j; j++)
if((i%j) == 0) isprime = false;
if (isprime)
System.out.println(i +" - is a prime number.");
}
}
}
I can not understand two things
1) Condition of second FOR loop:
j <= i/j;
Is this some kind of mathematical algorithm for finding primes?
My version of the condition looks like
j < i;
2) If in the condition of the second loop put i <= j instead of i < j, then the output of the program will be empty. Why?
Thank you for help!
Explanation of second question:
When I solved this problem, relying on "my" version of the definition of a prime number, my code looked like this:
for(i=2; i < 100; i++) {
isprime = true;
for (j=2; j <= i; j++)
if((i%j) == 0) isprime = false;
if (isprime)
System.out.println(i +" - is a prime number.");
}
Pay attention to the condition of the second cycle:
i <= j. Less or equal
If you rely on "my" definition of a prime number, then the equal sign in the condition should be.
Try running the program. The output will be empty.
But if the condition removes the equal sign for (j=2; j < i; j++), the program will work correctly.
what is the reason?
Let's focus onto these for loops.
for(i=2; i < 100; i++) {
isprime = true;
for (j=2; j <= i/j; j++)
if((i%j) == О) isprime = false;
if (isprime)
System.out.println(i +" - is a prime number.");
}
The first loop iterates through all numbers you want to test. Easy enough to understand, it simply tells "I want to perform the following test on all numbers from 2 to 100".
for (j=2; j <= i/j; j++)
if((i%j) == О) isprime = false;
Now this loop is pure math.
Mathematically, a prime number :
is a natural number greater than 1 that cannot be formed by
multiplying two smaller natural numbers.
(source : Wikipedia)
You therefore iterate through all numbers that, multiplied, would form i.
But do you really need to ?
If, as an example, i = 3*25, do you need to iterate all the way to 25 to know i is not a prime number ?
The answer is obviously no, since after testing for j=3, you already know i is composite.
Mathematically, multiple algorithms exist to check whether a number is prime or composite., but a reasonably correct way to do it is to check whether a number is a multiple of any number between 2 and its own square root. You are performing a rounded-up version of this.
Checking for all numbers between 2 and i is redundant for reasons cited above.
EDIT : Answer to 2)
When using
for (j=2; j <= i; j++)
if((i%j) == 0) isprime = false;
you are telling the compiler to stop looping after performing the test on j==i. Of course, when j equals i, (i%j) == 0 always evaluates to true.
In non-informatical terms, you are checking whether a number is composed of any number, excluding 1, including itself, whereas you should check whether it is composed of any number, excluding 1 and itself.
This is due to Java's way of implementing for loops : they stop when the middle condition evaluates to false.

Setting an initial value outside and inside loop

I was wondering what would be a real difference between setting up code like this
public boolean stringE(String str) {
int count = 0;
for (int i =0; i < str.length(); i++) {
if (str.charAt(i) == 'e') {
count += 1;
}
}
return (count >=1 && count<=3 );
}
and this
public boolean stringE(String str) {
for (int i =0; i < str.length(); i++) {
int count = 0;
if (str.charAt(i) == 'e') {
count += 1;
}
}
return (count >=1 && count<=3 );
}
I know the first one is right but what would make it difference by setting "int count =0" inside "for loop". Wouldn't it still add 1 to the count =0 ?
The second case won't compile, since count won't be recognized in the return statement, since the scope of the count variable is only inside the for loop in that case.
That's why you have to declare count outside the for loop.
Another problem with the second case, as mentioned by Dici, is that you reset count to 0 in each iteration of the loop, which means the loop wouldn't count what it is supposed to count.
In second case, the variable count is not visible outside for loop so that will create error at return statement. Also the logic is wrong since it will get reset everytime.
You can always try - and in this case, you might notice that the second one won't compile. It's syntactically incorrect.
In Java, when you define a variable, it only exists in the scope of the braces {} it's defined in. If you define a variable inside a loop, it only exists inside the loop. You can't use count outside the braces it's defined in.
Also, I doubt even the first program is semantically correct - you always return during the first iteration, which is unlikely to be what you want.

Why does this prime checker work, and not work if I try to make it more efficient

Below is one of the first programs I made (with help from the Internet) in Java. It is a program that checks if a given integer is prime or not and prompts the user with feedback. If the user input is not an integer it outputs that it is not an integer. The latter also happens when Big Integers are entered. This is the code:
import java.util.Scanner;
class BasicPrime1 {
public static void main(String[] args) {
try {
System.out.println("Enter an Integer: ");
Scanner sc = new Scanner(System.in);
int i;
int number = Integer.parseInt(sc.nextLine());
// 1 and numbers smaller than 1 are not prime
for (i = 1; number <= i;) {
System.out.println("NOT a prime!");
break;
}
// Number is not prime if the remainder of a division (modulus) is 0
for (i = 2; i < number; i++) {
int n = number % i;
if (n == 0) {
System.out.println("NOT a prime!");
break;
}
}
// I do not understand why the if-statement below works.
if(i == number) {
System.out.println("YES! PRIME!");
}
}
catch(NumberFormatException nfe) {
System.out.println("Not an integer!");
}
}
}
This program does his job, but I do not know why the part with the if-statement works. How is it possible that "i == number" gives a value of true (it prints out "YES! PRIME" when you enter a prime)? The local variable i gets incremented in the for-loop, but the if-statement is outside of the for-loop.
/edit the paragraph below is nonsense as Jim Lewis points out
Thinking about it now, the only reason I can think of that this is the case is because the == operator checks if the i-'object' and number-'object' belong to the same 'type' (i.e., have a reference to the same object). Since they both belong to the type of primitive integers this program catches the integers (other input throws a NumberFormatException which is caught and outputs "Not an integer"). The ones that are primes pass the first for-loop and then the magical if-statement gives "true" and it prints out "YES! PRIME!".
Am I on the right track?
I have improved this program by removing the magical if-statement and changing it for an if-else-statement like this: (/edit fixed problem with code thanks to answer of ajb)
boolean factorFound = false;
for (i = 2; i < Math.sqrt(number) + 1; i++) {
int n = number % i;
if (n == 0) {
factorFound = false;
break;
}
else {
factorFound = true;
}
}
if(factorFound == false) System.out.println("NOT a prime!");
if(factorFound == true) System.out.println("YES! PRIME!");
By only going up to the square root of the input number the calculation time improves (I know it can be even more improved by only checking odd numbers or using a AKS Primality Test, but that is beside the point).
My main question is why I could not improve the efficiency of the first program (with the magical if-statement) in the same manner. When I enhance the for-loop like this "(i = 2; i < Math.sqrt(number) + 1; i++)" in the first program it does no longer print out "YES! PRIME!" when you input a prime. It gives a blank. Even if my previous explanation is correct - which it is probably not - this is not explained.
You may enlighten me.
ANSWER: int i is outside of scope of for-loop and after going through the for-loop multiple times upto number the value of i will reach the value number, when we can be sure it is a prime. Furthermore, after checking the disappearing "YES! PRIME!" statement once again it turns out it is actually possible to change number in both the if-statement and for-loop to ( Math.sqrt(number) + 1 ) and have working code. So the question was based on a false premise.
i is declared outside the for loops, so its value is still in scope and available after the loop
finishes (nothing to do with comparing data types or anything like that!).
If no divisors were found, the i < number loop condition will eventually
fail, with i == number. (If the loop finds a divisor and hits the break statement,
that condition no longer holds).
When you do the sqrt optimization, the end condition of the loop is changed,
so i == number no longer holds after the loop exits, even if the number is prime.
In my opinion it would be more clear to explicitly set a flag (e.g. isPrime=0 just
before breaking out of the loop), then check that flag rather than looking at the
loop variable to see whether the loop completed or not.
// I do not understand why the if-statement below works
Explanation: Because i has been incremented until it equals number. If you stop at sqrt(number) then the if statement will always fail.
By the way I don't like using square root with integers. I like this better for a isPrime function:
if (number < 2) return false;
if (number > 2 && number % 2 == 0) return false;
for (int i = 3; i * i <= number; i = i + 2)
if (number % i == 0) return false;
return true;

Loop logic (Java)

This may seem silly, but I'm a bit confused about the following code:
public class Loops{
public static void main(String[] args) {
int i = 0;
int j = 2;
int k = 0;
boolean continue = i<j;
while (continue && k < 2) {
i++;
j--;
k++;
}
System.out.println(j);
}
}
This program prints 0, but I just don't understand why it doesn't print 1. The way I see it, after one loop i = j = 1. And thus continue = false. So if anyone can explain to me the logic behind this I would greatly appreciate it!
continue does not reevaluate itself after every loop iteration because he is defined outside of the loop.
instead, check in the loop condition for i < j
while (i<j && k < 2) {
i++;
j--;
k++;
}
Your loop would be optimized by compiler as:
boolean continue = i<j;
while (true && k < 2)
and finally
while (k < 2)
So it need to loop two times to exit
After the first loop: j == 1, k == 1
After the second loop: j == 0, k == 2, exit now
this is why finally j == 0
Try out putting condition inside a while():
while (i<j && k < 2)
Continue is only set outside of loop body, it is never updated during the loop. Thus continue is set to true before the loop starts and then never modified again.
First of all, your continue variable always evaluates to true (0 < 2) so we can ignore it.
First iteration:
i ends up evaluating to 1.
j ends up evaluating to 1.
k ends up evaluating to 1.
As k < 2, we do another iteration.
Second iteration:
i ends up evaluating to 2.
j ends up evaluating to 0.
k ends up evaluating to 2.
As k == 2, we exit the loop.
Then we print j, which evaluates to 0.
You only set the value of variable 'k' once and consequently continue as well. You need to re-evaluate the conditional expression inside the loop as well.
That said, I would suggest you refrain from using 'continue' as a varible name; I'm fairly certain it is a reserved word in many languages.

Categories

Resources