Been trying to figure this one out for the last 3 hours and so hard to find any search results for "nesting for loop inside for loop", so I must ask this question and somebody can help clarify, as much of an amateur question this is, will much appreciate any and all help.
So I have this block of code underneath, for a beginners looping exercise I found at http://www.w3resource.com/php-exercises/php-for-loop-exercises.php
on question 3 of that page. The end result should be on that page as well.
<?php
for($a = 1; $a <= 5; $a++) {
for($b = 1; $b <= $a; $b++) {
echo "*";
if($b < $a) {
echo " ";
}
}
echo "<br />";
}
?>
It turns out like a triangle shape made up of 15 little *
I am trying to figure out exactly how this works, as even though the site has an answer, I want to understand so I can write things myself instead of copy pasting.
Below is what I have been able to make out after reading php.net and also trying to look for a solution on Google.
So, the $a for loop starts off as true so loop continues onto the $b FOR loop, it is true so it will echo *, At this point $b is not < $a as loop is not yet over so the ++ have not been added yet and if statement is false, so we <br /> and re-run loop.
Second time around. Now $a=2 and for loop is still true so it will go on to $b for loop and echo *. This is where I get confused. The $b has ++ at the end of its statement, so doesn't it mean that after loop 1 $b = 2 and if is still false ?
In my head I keep thinking it should print out like:
<br />* <br /> * <br />
instead of this:
<br />* <br /> * * <br />
My conclusion.
The $b value will reset back to 1 after each loop and repeats itself until if statement is false.
OR
The * that get printed are stored and will be the automatic starting point at the beginning of each loop. I understand that if doing a simple print for a for($i=0;$i<11;$i++) loop will carry the value over, however in my situation, a printed * is not a value, so it shouldn't be carried over to a new loop.
OR
I am just completely off with both my conclusions.
Either way, its been confusing me so badly.
Sorry for long explanation.
Thanks.
Let's take things one step at a time
Outer Loop
for($a = 0; $a <= 5; $a++) {
//inner loop here
echo "<br>"; //after the inner loop has executed, start a new line
}
Start at 0, go up to 5 and do whatever is written inside. Now that means two things will happen for each iteration
1) Inner loop will be executed for every iteration of the outer loop
2) An HTML row break will be printed for every iteration of the outer loop
Now what does the Inner Loop do?
for($b = 1; $b <= $a; $b++) {
echo "*";
if($b < $a) {
echo " "; // $b<$a means we still have more stars to print on this line
}
}
Start at 1, go up to the value of $a, this $a will come from the outer loop and will be 1 for the first run, 2 for second up to 5. And while doing this, print a *; that means for the first time 1 star will be printed because loop will start at 1 and end at 1. For the second time 2 stars, 3rd time three stars and so on.
Now after printing the star, see if this is the last star that this iteration had to print, if it is not that then print a space so that the next time a star is printed there is a space in between.
That's about it :) Note that your outer loop starts at 1, it should start at 0 to form the required shape correctly.
Now if you are still confused about the $b<$a thing, just get rid of it and run your code again and you will notice nothing much has changed except that there are no spaces between the stars and it will be a little easier to understand
for($b = 1; $b <= $a; $b++) {
echo "*";
}
And oh, ++ after a variable means increment its value by 1. In a for loop that means on the next run add 1 to the value of the counter. You can also write it as
for($a=0; $a<=5; $a=$a+1) // thats the same as $a++;
If you wanted the value to increment by more than 1 you could say
for($a=0; $a<=5; $a=$a+2) // a will be 0 , 2, 4
Fiddle
Related
I am running a for loop 10 times in order to populate data in a data table. In doing this, I wanted to use number_format in order to format the numbers. However, when I apply the number_format the For loop for some reason runs one additional time.
It works just fine when I exclude the number_format. Can anyone explain why this happens?
<?php
foreach($data['data'] as $result) {
For ($n = 0; $n <= 10; $n++){
echo "<td>";
echo number_format($result[$n], 0, ".", ",");
echo "</td>";
}
}
?>
TL;DR: Your loop will always run an additional time. Assuming that there are no errors in your number_format function call, all you have to do to get this to run 10 times is change your code to for($n = 0; $n < 10; n++). Note the use of < and not <=.
For loops are really just syntactical sugar for while loops. The statement for(initial_statement; bound_condition; loop_statement) { code; } is equivalent to
initial_statement;
while(bound_condition) {
code;
loop_statement;
}
Which, functionally, is equivalent to
initial_statement;
while(true) {
code;
loop_statement;
if(!bound_condition) break;
}
This means that if you want a loop to run, say, 2 times, and you write for($i = 0; $i <= 2; $i++) your code will loop as follows:
$i = 0
i++; (i now equals 1)
i <= 2 (condition is true, so continue)
$i = 1
i++; (i now equals 2)
i <= 2 (condition is true, so continue)
$i = 2
i++; (i now equals 3)
i <= 2 (condition is FALSE, so break)
Using the <= operator when your control variable starts at 0 causes an extra iteration to occur, since there are three integer values of i such that 0 <= i <= 2 (0, 1, and 2). To ensure that there are only two iterations, use the < operator, and now the loop will only be executed for values in the domain 0 <= i < 2 (0 and 1).
If you are still bent on using the <= operator and are fine with a non-zero-based iteration count, then you can simply change the initial value of i to 1 to offset the error.
By the way your code is written, I assume that you wish for your inner loop to run 10 times, not 11. This would explain why you are getting an extra iteration, and the issue is quite unrelated to the use of number_format. If you are only getting 10 iterations when you don't use that function, you might want to make sure that the statement 1 == 1 evaluates to true in your PHP interpreter.
Additionally, as a code styling issue, I would recommend using consistent case in your statements; you write foreach (lowercase) but also use For (uppercase). The convention is to use lowercase for both.
I have no clue why you would be only getting 10 iterations without number_format. You might be counting incorrectly? Try changing it to < and see if that resolves your issue.
I'm a newbie to php and I've understood all other loops in php but the question is I cannot understand how the for loops works for ex:
Here is the code;
$a = 0;
$b = 0;
for ($i=0; $i < 5; $i++) {
$a += 10;
$b += 5;
}
echo("At the end of the loop a=$a and b=$b");
When I execute this script the value of a = 50 and b = 25!
Is it multiplying the a value with i's increment value? like 10 * 5 = 50.
You start with $i=0, then you do $a+10 and $b+5 as long as $i <5
$i=0, $a=10, $b=5
$i=1, $a=20, $b=10
$i=2, $a=30, $b=15
$i=3, $a=40, $b=20
$i=4, $a=50, $b=25
$i=5, now the loop stops because $i is no longer <5
Your loop runs five times. Each time through the loop you add 10 to the value of $a. Doing that five times gives you 50.
This is the way it works.
Let's say you have a no dollars. And I tell you that I will give you a dollar everytime you do 5 chores. However, I will only give you 5 dollars. At first you have no dollars and after one chore I give you 5 dollars. Now you have 5 dollars. You do another chore and I give you another 5, bringing you to ten. I have now given you two dollars. I give you another 5 - you have 15. I give you another - 20 - and one more; bringing you to 25 dollars. Now I have given you my limit of dollars, and our loop is complete.
In this story, my dollars are your $i value. Beginning at 0, working up to 5. Your chores are your $b values, which are added to every time.
Code example:
for ($dollars=0; $dollars < 5; $dollars++) {
$chores += 5;
}
+= is not increment its an assignment operator.
http://php.net/manual/en/language.operators.assignment.php
As I mentioned in the comments, and others in their answers. += will add the value to on the right to the value on the left. so in a loop its like this
step 0 $a = 5 ( 0+5)
step 1 $a = 10 (5[previous iteration exit value]+5 )
step 2 $a = 15 (10[previous iteration exit value] + 5)
so on....
Of note is you can also do -= *= etc. and .=or append all the same kind of operation.
The for statement is used when you know how many times you want to execute a statement or a block of statements.
Syntax:
for (initialization; condition; increment){
code to be executed;
}
The initializer is used to set the start value for the counter of the number of loop iterations. A variable may be declared here for this purpose and it is traditional to name it $i.
Example
The following example makes five iterations and changes the assigned value of two variables on each pass of the loop −
<html>
<body>
<?php
$a = 0;
$b = 0;
for( $i = 0; $i<5; $i++ ) {
$a += 10;
$b += 5;
}
echo ("At the end of the loop a = $a and b = $b" );
?>
</body>
</html>
This will produce the following result −
At the end of the loop a = 50 and b = 25
For loop is entry condition loop. It evaluate condition first, so the statement block associated with the loop won't run even once if the condition fails to meet
The statements inside this for loop block will run 5 times, the value of $i will be 0 to 4;
Imagine the loops are running separately.
$a=0;
$b=0;
for ($i = 0; $i < 5; $i++){
echo $a += 10;
echo '<br>';
}
And the output like this.
10
20
30
40
50
Now another Loop
for ($i=0; $i < 5; $i++) {
echo $b += 5;
echo '<br>';
}
And the output like this
5
10
15
20
25
In each iteration it adds 10 and 5 to previous number of iteration using the assignment operator x += y.
I almost feel stupid asking such basic question, anyway.
I just started learning php on my own by reading some books, before that I used to wander from one online tutorial to another, I should have started from the very basic but I dived head first into if else, foreach, while, arrays etc.
Despite grabbing the concept of those I now realized there are few things that confuse me.
So I was doing this simple exercise, print out the numbers from 1 to 5 using ++ and the *= multiply the power of 2.
$i = 1;
echo $i.'-'.++$i.'-'.++$i.'-'.++$i.'-'.++$i;
Seems all good here, my question is why if I echo $i now it returns 5?
Do I have to reassign the 1 to $i if I want to reuse it later?
I tried to use the same pattern to echo the powers of 2 but all I got was the first and last multiplication.
$p = 1;
echo $p .'-'.$p*= 2 .'-'.$p*= 2 .'-'.$p*= 2 .'-'.$p*= 2 .'-'.$p*= 2 .'-';
Does that mean that I cannot use concatenation if I use combined operators and I would have to echo each line?
Keep in mind I'm restricted to use what is explained in the first two chapters.
Looks like you want a for loop.
$stringVar = "";
for($i=1;$i<6;$i++) {
$stringVar .= "$i -";
}
echo $stringVar;
I'll leave the second one as an exercise for you.
A simple variable (like your $i) stores one digit
so if you do a ++$i, you do the same as $i = $i +1
that means you change the content of your variable
$i = 1;
$i_originalValue = $i;
echo $i.'-'.++$i.'-'.++$i.'-'.++$i.'-'.++$i;
echo $i; //prints 5
echo $i_originalValue; //prints 1
I know I have done this in Javascript once, but how can I make it in PHP?
Basically I want to do this:
if (empty($counter)){
$counter = 1;
}else{
"plus one to $counter" ($counter++?)
}
But it didn't work when I tried. How would I go about doing this?
Thank you :)
EDIT: This is so I can do:
if ($counter == 10){
echo("Counter is 10!");
}
EDIT:
This is all in a "while()" so that I can count how many times it goes on, because LIMIT will not work for the query I'm currently doing.
why the extra if into the while?
i would do this:
$counter = 0;
while(...)
{
(...)
$counter++;
}
echo $counter;
To increment a given value, attach the increment operator ++ to your integer variable and place it within your while loop directly, without using a conditional expression to check if the variable is set or not.
$counter = 1;
while(...){
echo "plus one to $counter";
$counter++;
}
If your counter is used to determine how many times your code is to be executed then you can place the condtion within your while() expression:
while($counter < 10){
echo "plus one to $counter";
$counter++;
}
echo("Counter is $counter!"); // Outputs: Counter is 10!
You're going to have to learn the basics of how PHP outputs to the screen and the other controls along with it.
if (empty($counter)){
$counter = 1;
}else{
echo 'plus one to $counter';
$counter++;
}
Something along those lines will work for you.
PHP is pretty flexible with what you throw at it. Just remember, statements need a semicolon at the end, and if you want to output to the screen, (in the beginning) you'll be relying on echo statements.
Also, when dealing with echo statements, notice the difference between single quotes and double quotes. Double quotes will process any contained variables:
$counter = 3;
echo "plus one to $counter"; // output: plus one to 3
echo 'plus one to $counter'; // output: plus one to $counter
I'm attempting to solve Project Euler in PHP and running into a problem with my for loop conditions inside the while loop. Could someone point me towards the right direction? Am I on the right track here?
The problem, btw, is to find the sums of all prime numbers below 2,000,000
Other note: The problem I'm encountering is that it seems to be a memory hog and besides implementing the sieve, I'm not sure how else to approach this. So, I'm wondering if I did something wrong in the implementation.
<?php
// The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
// Additional information:
// Sum below 100: 1060
// 1000: 76127
// (for testing)
// Find the sum of all the primes below 2,000,000.
// First, let's set n = 2 mill or the number we wish to find
// the primes under.
$n = 2000000;
// Then, let's set p = 2, the first prime number.
$p = 2;
// Now, let's create a list of all numbers from p to n.
$list = range($p, $n);
// Now the loop for Sieve of Eratosthenes.
// Also, let $i = 0 for a counter.
$i = 0;
while($p*$p < $n)
{
// Strike off all multiples of p less than or equal to n
for($k=0; $k < $n; $k++)
{
if($list[$k] % $p == 0)
{
unset($list[$k]);
}
}
// Re-initialize array
sort ($list);
// Find first number on list after p. Let that equal p.
$i = $i + 1;
$p = $list[$i];
}
echo array_sum($list);
?>
You can make a major optimization to your middle loop.
for($k=0; $k < $n; $k++)
{
if($list[$k] % $p == 0)
{
unset($list[$k]);
}
}
By beginning with 2*p and incrementing by $p instead of by 1. This eliminates the need for divisibility check as well as reducing the total iterations.
for($k=2*$p; $k < $n; $k += $p)
{
if (isset($list[k])) unset($list[$k]); //thanks matchu!
}
The suggestion above to check only odds to begin with (other than 2) is a good idea as well, although since the inner loop never gets off the ground for those cases I don't think its that critical. I also can't help but thinking the unsets are inefficient, tho I'm not 100% sure about that.
Here's my solution, using a 'boolean' array for the primes rather than actually removing the elements. I like using map,filters,reduce and stuff, but i figured id stick close to what you've done and this might be more efficient (although longer) anyway.
$top = 20000000;
$plist = array_fill(2,$top,1);
for ($a = 2 ; $a <= sqrt($top)+1; $a++)
{
if ($plist[$a] == 1)
for ($b = ($a+$a) ; $b <= $top; $b+=$a)
{
$plist[$b] = 0;
}
}
$sum = 0;
foreach ($plist as $k=>$v)
{
$sum += $k*$v;
}
echo $sum;
When I did this for project euler i used python, as I did for most. but someone who used PHP along the same lines as the one I did claimed it ran it 7 seconds (page 2's SekaiAi, for those who can look). I don't really care for his form (putting the body of a for loop into its increment clause!), or the use of globals and the function he has, but the main points are all there. My convenient means of testing PHP runs thru a server on a VMWareFusion local machine so its well slower, can't really comment from experience.
I've got the code to the point where it runs, and passes on small examples (17, for instance). However, it's been 8 or so minutes, and it's still running on my machine. I suspect that this algorithm, though simple, may not be the most effective, since it has to run through a lot of numbers a lot of times. (2 million tests on your first run, 1 million on your next, and they start removing less and less at a time as you go.) It also uses a lot of memory since you're, ya know, storing a list of millions of integers.
Regardless, here's my final copy of your code, with a list of the changes I made and why. I'm not sure that it works for 2,000,000 yet, but we'll see.
EDIT: It hit the right answer! Yay!
Set memory_limit to -1 to allow PHP to take as much memory as it wants for this very special case (very, very bad idea in production scripts!)
In PHP, use % instead of mod
The inner and outer loops can't use the same variable; PHP considers them to have the same scope. Use, maybe, $j for the inner loop.
To avoid having the prime strike itself off in the inner loop, start $j at $i + 1
On the unset, you used $arr instead of $list ;)
You missed a $ on the unset, so PHP interprets $list[j] as $list['j']. Just a typo.
I think that's all I did. I ran it with some progress output, and the highest prime it's reached by now is 599, so I'll let you know how it goes :)
My strategy in Ruby on this problem was just to check if every number under n was prime, looping through 2 and floor(sqrt(n)). It's also probably not an optimal solution, and takes a while to execute, but only about a minute or two. That could be the algorithm, or that could just be Ruby being better at this sort of job than PHP :/
Final code:
<?php
ini_set('memory_limit', -1);
// The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
// Additional information:
// Sum below 100: 1060
// 1000: 76127
// (for testing)
// Find the sum of all the primes below 2,000,000.
// First, let's set n = 2 mill or the number we wish to find
// the primes under.
$n = 2000000;
// Then, let's set p = 2, the first prime number.
$p = 2;
// Now, let's create a list of all numbers from p to n.
$list = range($p, $n);
// Now the loop for Sieve of Eratosthenes.
// Also, let $i = 0 for a counter.
$i = 0;
while($p*$p < $n)
{
// Strike off all multiples of p less than or equal to n
for($j=$i+1; $j < $n; $j++)
{
if($list[$j] % $p == 0)
{
unset($list[$j]);
}
}
// Re-initialize array
sort ($list);
// Find first number on list after p. Let that equal p.
$i = $i + 1;
$p = $list[$i];
echo "$i: $p\n";
}
echo array_sum($list);
?>