Well, ths is a really newbie question, but couldn't find the proper keywords to get the answer.
I have a vector variable, $p.
I want to achieve this:
$n = 5;
$prev = $p[$n--];
$actual = $p[$n];
$next = $p[$n++];
The values i want should be:
$prev = 4;
$actual = 5;
$next = 6;
Instead of that, i get:
$prev = 5;
$actual = 4;
$next = 4;
I know i'm missing something, but i couldn't figure it out.
Thanks in advance
Just do the math yourself:
$prev = $p[$n - 1];
$actual = $p[$n];
$next = $p[$n + 1];
If you must use increment / decrement operators (for some strange reason), you can use:
$prev = $p[--$n];
$actual = $p[++$n];
$next = $p[++$n];
Note that your original code was failing, as jeremy points out, because increment and decrement operators modify the original value of the variable.
At the first search:
$prev = $p[$n--]
You are changing the value of n for the next operations, decreasing it by one. In
$next = $p[$n++];
You are increasing it again so n value is the same as the beginning. You should do what nickb told.
You are incrementing the same variable inline so:
$n doesn't stay as 5 when you do $n++ or $n--, you reassign the value to $n
$n-- = 4, so now $n is 4, not 5 so $n++ is 5, not 6
Related
I am having some problems with PHP.
I used while to sum a number's digits always that it has more than two digits, some how, it gets into an infinity loop.
e.g: 56 = 5 + 6 = 11 = 1+1= 2.
Here is the code:
$somaP = 0;
$numPer = (string)$numPer; //$numPer = number calculated previously
while (strlen($numPer) > 1){
for ($j = 0; $j < strlen($numPer); $j++){
$somaP = $somaP + (int)($numPer[$j]);
}
$numPer = (string) $somaP;
}
Can anyone help me? Guess it is a simple mistake, but I couldn't fix it.
You need to reset the value of $somaP in your while loop.
Currently it continues to increase its value every time through the loop.
Try this:
$numPer = (string)$numPer; //$numPer = number calculated previously
while (strlen($numPer) > 1){
$somaP = 0;
for ($j = 0; $j < strlen($numPer); $j++){
$somaP = $somaP + (int)($numPer[$j]);
}
$numPer = (string) $somaP;
}
Take a look at this line:
$numPer = (string) $somaP;
It seems that the length of $somaP is never lesser (or equal) than 1. So the length of $numPer is never lesser (or equal) than 1.
What are you trying to do?
It's unclear to me.
This for example would add every number in a string together?
E.g "1234" = 1+2+3+4 = 10
$total = 0;
for($i = 0; i < strlen($string); $i++){
$total += $string[$i];
}
echo $total;
This looks cleaner I would say:
$numPer = 56;
while ($numPer > 9){
$numPer = array_sum(str_split($numPer));
}
echo $numPer;
PHP handles all string <> number conversions for you, so no need to do (string) on a number unless really needed.
i feel a little bit stupid, but let's imagine, that i have a set of unix timestamps:
1375110404
1374660925
1374482694
1374242337
1373793867
1373632889
1373187141
1373021668
1372754021
1372599890
What i'm trying to achieve is simple: I just want to calculate the average time difference between these 10 timestamps. I just can't find the proper way for the calculation.
What i just tried was
1375110404 - 1374660925 = 449479
1374482694 - 1374242337 = 240357
1373793867 - 1373632889 = 160978
1373187141 - 1373021668 = 165473
1372754021 - 1372599890 = 154131
449479 + 240357 + 160978 + 165473 + 154131 = 1170418
1170418 / 5 = 234083,6
but that looks illogical to me. Any advice is greatly appreciated.
EDIT:
All these stamps come from a php array.
EDIT:
Thanks to Orangepill for pointing me to the right direction. Here's the final solution:
for($cnt = count($array), $res = 0, $i = 1; $i < $cnt; $i++) {
$res += $array[$i-1] - $array[$i];
}
echo $res/$cnt;
This calculates
1375110404 - 1374660925 = 449479
1374660925 - 1374482694 = 178231
1374482694 - 1374242337 = 240357
1374242337 - 1373793867 = 448470
1373793867 - 1373632889 = 160978
1373632889 - 1373187141 = 445748
1373187141 - 1373021668 = 165473
1373021668 - 1372754021 = 267647
1372754021 - 1372599890 = 154131
449479 + 178231 + 240357 + 448470 + 160978 + 445748 + 165473 + 267647 + 154131 = 2510514
2510514 / 10 = 251051.4
which looks correct to me.
The most straight forward way it to do it like you described.
$res =0;
for($x = 1, $num = count($array); $x < $num; $x++){
$res =+ $array[$x] - $array[$x-1];
}
echo $res/($num-1);
The current accepted answer will give incorrect results if the the timestamps are not in strict chronological order. That is, negative values will skew your average. I may be wrong, but I imagine that you don't want to count any time difference as a negative value, after all, you can't run 100m in -12 seconds!
I provide this answer as an alternative that will always give an average based on positive time differences regardless of the order of the times in the passed array:-
function array_average_diff(array $array)
{
$diff = 0;
for($i = 1; $i < count($array); $i++){
$diff += abs($array[$i] - $array[$i - 1]);
}
return $diff/count($array);
}
See it working
I'm having to pass 3 variables (int) within a single numeric string called $id. To do this I'm creating $id using padding which I can then explode to get the variables. It has to be numeric otherwise I'd use underscores between the variables. I'm using eleven zeros as padding as I know the variables won't have that many zeros. So currently if I have:
$int_one = 1;
$int_two = 2;
$int_three = 3;
That would be:
$id = "1000000000002000000000003";
To create the new Id I use:
$id = $int_one . "00000000000" . $int_two . "00000000000" . $int_three;
And to separate the Id I use:
$int_one = 0;
$int_two = 0;
$int_three = 0;
if (strpos($id,"00000000000") !== false) {
$id = strrev($id); // Reversed so 0's in int's don't get counted
$id = explode("00000000000", $id);
// Set numbers back the right way
$int_one = strrev($id[2]);
$int_two = strrev($id[1]);
$int_three = strrev($id[0]);
}
This runs into problems when an individual variables is 0. Is there a way to overcome this or does it need a major rethink?
EDIT: $id is supposed to be a numeric string not int
Needs to handle int variables between 0 - 2147483647
You can just use some string magic to assure that no number has more than one zero in a row, and delimit the values using '00'. This generates a numeric string that can be uniquely decoded no matter the size or composition of the ints.
$a = 100;
$b = 0;
$c = 120;
// Encode;
$id = str_replace('0', '01', $a).'00'
.str_replace('0', '01', $b).'00'
.str_replace('0', '01', $c);
// $id = "101010001001201"
// Decode;
$tmp = split('00', $id);
$a2 = intval(str_replace('01', '0', $tmp[0]));
$b2 = intval(str_replace('01', '0', $tmp[1]));
$c2 = intval(str_replace('01', '0', $tmp[2]));
// $a2 = 100, $b2 = 0, $c2 = 120
Is there a way to overcome this or does it need a major rethink?
Yes, you'll need to rethink that. Why do you need to do it that way? Simply create a function with three parameters and pass the three ints in:
function foo($int1, $int2, $int3) {
}
Your example uses strings, not ints by the way, so you aren't even following your own requirements.
You could try this method:
$int_one = 1;
$int_two = 2;
$int_three = 3;
$id = $int_one * 1000000000000 + $int_two * 1000000 + $int_three;
// This will create a value of 1000002000003
To reverse the process:
// Get the modulo of $id / 1000000 --> 3
$int_three = $id % 1000000;
// Recalculate the base id - if you would like to retain the original id, first duplicate variable
// This would make $id = 1000002;
$id = ($id - $int_three) / 1000000;
// Again, get modulo --> 2
$int_two = $id % 1000000;
// Recalculate base id
$id = ($id - $int_two) / 1000000;
// Your first integer is the result of this division.
$int_one = $id;
i want after i've been submit form it can show hit counter..
but i want after it reach "20" it can back to zero..bcoz the limit of submit is 20 times so it can't over the limit.
how do i make it works?I've been try to this code...
<?
$limit="20";
$Query_counter=mysql_query("SELECT model FROM inspec");
$Show_counter=mysql_fetch_array($Query_counter);
$show_counter = $show_counter["model"]+1;
if($show_counter > $limit[0]) {
$show_counter = 0;
}elseif ($show_counter > $limit[1]) {
$show_counter = 0;
}
$Query_update=mysql_query("UPDATE inspec SET model=$Show_counter");
$Show_counter=number_format($Show_counter);
$Show_counter=str_replace(",",".",$Show_counter);
echo "Hit:</br><strong>$show_counter</strong>";
?>
To make a counter go up to a certain value then loop back to zero, you can use the modulus operator, which in a lot of languages (including PHP and MySQL) is %
$x = 0;
$limit = 4;
for ($i = 0; $i < 10; ++$i) {
$x = ++$x % $limit;
echo $x;
}
// 1, 2, 3, 0, 1, 2, 3, 0, 1, 2
I hope that makes enough sense. I can't really figure out from the question what exactly you want... Perhaps something like this?
UPDATE `mytable` SET `mycounter` = (`mycounter` + 1) % {{the limit}}
The concept here is to test to see if the variable you're incrementing exceeds some acceptable range as a result of the next increment. Simple increment the variable, then test its value.
In your case, just add a test after you increment the counter:
$show_counter = $show_counter["model"]+1;
if($show_counter > $limit){
$show_counter = 0;
}
Be sure to define $limit to whatever number you want to cycle on.
If you want to do this for multiple thresholds you can add additional tests. Note that you could hard-code $limit to any number or any variable you want, it's just the thing you're testing against.
<?
$Query_counter=mysql_query("SELECT model FROM inspec");
$Show_counter=mysql_fetch_array($Query_counter);
$show_counter = $show_counter["model"]+1;
$x = 0;
$limit = 20;
for ($i = 0; $i < 30; ++$i) {
$x = ++$x % $limit;
echo $x;
}
$Query_update=mysql_query("UPDATE inspec SET model= (model + 1) % 20");
$Show_counter=number_format($Show_counter);
$Show_counter=str_replace(",",".",$Show_counter);
echo "Hit:</br><strong>$show_counter</strong>";
?>
What's the difference between ++$i and $i++ in PHP?
++$i is pre-increment whilst $i++ post-increment.
pre-increment: increment variable i first and then de-reference.
post-increment: de-reference and then increment i
"Take advantage of the fact that PHP
allows you to post-increment ($i++)
and pre-increment (++$i). The meaning
is the same as long as you are not
writing anything like $j = $i++,
however pre-incrementing is almost 10%
faster, which means that you should
switch from post- to pre-incrementing
when you have the opportunity,
especially in tight loops and
especially if you're pedantic about
micro-optimisations!"
- TuxRadar
For further clarification, post-incrementation in PHP has been documented as storing a temporary variable which attributes to this 10% overhead vs. pre-incrementation.
++$i increments $i, but evaluates to the value of $i+1
$i++ increments $i, but evaluates to the old value of $i.
Here's an example:
$i = 10;
$a = $i++;
// Now $a is 10, and $i is 11
$i = 10;
$a = ++$i;
// Now $a is 11, and $i is 11
There is sometimes a slight preformance cost for using $i++. See, when you do something like
$a = $i++;
You're really doing this:
$temporary_variable = $i;
$i=$i+1;
$a=$temporary_variable;
++$i is pre-incrementation
$i is incremented
the new value is returned
$i++ is post-incrementation
the value of $i copied to an internal temporary variable
$i is incremented
the internal copy of the old value of $i is returned
++$i //first increment $i then run line
$i++ //first run line then increment $i
this example elplains simply
<?php
$x = 10;
echo $x++. ' '.$x; // the result is 10 and 11
echo '<br>';
$y = 10;
echo ++$y. ' ' .$y; // the result is 11 and 11
// so the $x++ is not showing +1 at first but the next time
// and the ++y is showing +1 first time but not increasing next
in this case there is no difference:
for($i = 0;$i<3;++$i)var_dump $i;
/*
int(0)
int(1)
int(2)
*/
for($i = 0;$i<3;$i++)var_dump $i;
/*
int(0)
int(1)
int(2)
*/
but:
for($i = 0;$i<3; $j = ++$i )var_dump($j);
/*
NULL
int(1)
int(2)
*/
for($i = 0;$i<3; $j = $i++ )var_dump($j);
/*
NULL
int(0)
int(1)
*/
Difference is: ++$i will increment $i variable and return updated value, while $i++ will return original value, so increment it.
$prefix = 1;
$postfix = 1;
echo ++$prefix; // 2
echo $postfix++; // 1
To explain jldupont's point:
$i = 1;
$x = $i++;
echo $x; // prints 1
$x = ++$i;
echo $x; // prints 3
Another way of looking at pre and post incrementing is that it's shorthand for combining 2 statements.
Pre-incrementing
// long form
$y = $y + 1;
$x = $y; // any statement using $y
// shorthand
$x = ++$y; // the same statement using $y
Post-incrementing
// long form
$x = $y; // any statement using $y
$y = $y + 1;
// shorthand
$x = $y++; // the same statement using $y
$i++ is known as post-increment. It increments the value of $i only after assigning the original value of $i to $j first.
++$i is known as pre-increment. It increments the value of $i before assigning the value to $j, so the updated value of $i will be assigned to $j.
Hence,
$i = 4;
$j = $i++;
// Now, $i = 5 and $j = 4
$i = 4;
$j = ++$i;
// Now, $i = 5 and $j = 5
These theories apply in a similar manner for decrementing as well.
Hope this helps!
It's probably best-illustrated by an example...
Post-increment:
$zero = 0;
$n = $zero++; //$n is zero
Pre-increment:
$zero = 0;
$n = ++$zero; //$n is one
Short answer:
Prefix increases the value and returns the value increased
Postfix increases the value and returns the value before it was increased
Prefix is faster
Long answer: If you think a little about it, how you would implement those yourself, you will probably realize why prefix is faster. Truth to be told, postfix is actually (often) implemented using prefix:
const T T::operator ++ (int) // postfix
{
T orig(*this);
++(*this); // call prefix operator
return (orig);
}
Avoid postfix unless you have a specific reason not to. The difference in speed can be quite a lot for complex datatypes.
I actually looked this up a few days ago. Heres my source.
The main purpose of the post-fix increment operator is usage like this:
while(*condition*)
$array[$i++] = $something;
This is a very elegant way, how to get around some array iterations.
Breakdown:
Variable $something will be assigned to the array element indexed with $i
Variable $i will be incremented
Iteration is at the end, condition will be checked
In all other cases, you should use the prefix operator. It makes the code much more clear (You can be sure, that you already work with the incremented value of particular variable).
I ran the following code to test if ++$i is 10% faster than $i++. I admit, the code does not have a stable outcome but even then I should at least have seen some numbers near the 10%. The highest I got was 4-4.5% approximately.
<?php
$randomFloat = rand(0, 10) / 10;
$before1 = microtime(true);
for($i=0; $i <1000000; ++$i){
$rand = (rand(0, 10) / 10) * (rand(0, 10) / 10);
}
$after1 = microtime(true);
echo 'it took '.($after1-$before1) . ' seconds fot ++$i<br />';
$before2 = microtime(true);
for($i=0; $i <1000000; $i++){
$rand = (rand(0, 10) / 10) * (rand(0, 10) / 10);
}
$after2 = microtime(true);
echo 'it took '.($after2-$before2) . ' seconds fot $i++<br /><br />';
echo '++$i is '.((($after1-$before1)*100)/($after2-$before2)-100).'% faster than $i++';
Both operators still do what their syntax implies: to increment. Regardless of prefix or postfix, the variable is sure to be incremented by 1. The difference between the two lies in their return values.
1. The prefix increment returns the value of a variable after it has been incremented.
2. On the other hand, the more commonly used postfix increment returns the value of a variable before it has been incremented.
// Prefix increment
let prefix = 1;
console.log(++prefix); // 2
console.log(prefix); // 2
// Postfix increment
let postfix = 1;
console.log(postfix++); // 1
console.log(postfix); // 2
To remember this rule, I think about the syntax of the two. When one types in the prefix increment, one says ++x. The position of the ++ is important here. Saying ++x means to increment (++) first then return the value of x, thus we have ++x. The postfix increment works conversely. Saying x++ means to return the value of x first then increment (++) it after, thus x++.