<?php
$i == array(1, 2);
$j == array(a, b);
$m == count($j);
$n == count($i);
for ( $i = 0; $i < $m; i++ )
{
for ( $j = 0; j < $n; j++)
{ echo $i."x"$j; }
}
?>
The error is referencing line 6: for ( $i = 0; $i < $m; i++ )
for ( $i = 0; $i < $m; $i++ )
Note the dollar sign I added before the i++
Same goes for your other for statement:
for ( $j = 0; $j < $n; $j++ )
Wierd error indeed, but it i is not a variable (although PHP might flag a E_NOTICE and convert it to 'i'. You want to reference your variable, so you must add a $ before.
Most likely what you want is:
<?php
$iArray = array(1, 2);
$jArray = array('a', 'b');
$n = count($iArray);
$m = count($jArray);
for ( $i = 0; $i < $n; $i++) {
for ( $j = 0; $j < $m; $j++) {
echo $iArray[$i] . "x" . $jArray[$j];
}
}
?>
The things I changed:
== is used for comparison, = is used for assignment
The second array I assumed you wanted the string literals 'a' and 'b', but you could have also wanted $a and $b if you declared those variables somewhere else
you assign $i to an array, but then in your for loop you overwrite it with $i = 0. You most likely want two variables
missing $s, like I mentioned above
$m was being used for the number of variables in $jArray, but you used it to iterate over $iArray
So just a few pointers, brush up on you PHP and try to make sure your code works with every little change. Make 1 modification, then run it. It is very easy to get lost in syntax for PHP since it is such a dynamic scripting language
You have a bunch of equality checks there. I'm assuming you were actually assigning variables rather than checking for equality.
Change all == equality checks to assignments (=)
You also have improper concatenation on line 9 and I added a comment pointing out another possible error.
$i == array(1, 2);
$j == array($a, $b); // <--Put in $ signs if these are variables in the array
$m == count($j);
$n == count($i);
for ( $i = 0; $i < $m; $i++ )
{
for ( $j = 0; $j < $n; $j++)
{ echo $i."x".$j; }
}
Related
I knew that we use continue to jump to the next iteration in loop
For example
$x = 0;
for( $i = 0; $i < 10; $i++ ) {
if( $i%2 == 0 ) {
continue;
}
$x = $x + $i;
}
In this case we use continue to skip the even number, but we can do this instead
$x = 0;
for( $i = 0; $i < 10; $i++ ) {
if( $i%2 != 0 ) {
$x = $x + $i;
}
}
Can anyone show me some cases that we MUST use continue instead of only using opposite condition.
I have a multidimentional array of 5 items and I want that my loop would compare it like:
1 -> 2, 1 -> 3, 1 -> 4, 1 -> 5, 2->1, 2->3, 2->4, 2->5......// so on and 5 -> 4 in the end.
The problem is that after my array $i value matches 1 and $j value matches 3, the unset is done and the $i value becomes 2 (which is correct) and $j value becomes 4 instead of 3. Could someone tell me why and what I'm doing wrong?
My loop is:
for ($i = 0; $i <= count($myArray); $i++) {
for ($j = $i+1; $j <= count($myArray); $j++) {
if (
// condition 1
&& // condition 2
) {
unset($myArray[$i]);
$i++;
}
}
}
I think that's the problem is when you unset the element in the array, you increment the counter of the loop $i. In this way, the elements of the array that are not configured are removed, this empty array position will be maintained, it will not be reordered, you will have to do it manually or using array_values method.
In the last tour of the array, it will break because you are comparing the number of array elements as equal. You must use index < count($array)
The code would be like this:
for ($i = 0; $i < count($myArray); $i++) {
for ($j = $i+1; $j < count($myArray); $j++) {
if (
// condition 1
&& // condition 2
) {
unset($myArray[$i]);
// $i++;
}
}
}
try something like this
for ($i = 0; $i <= count($myArray); $i++) {
for ($j = 0; $j <= count($myArray); $j++) {
if ($j!=$i)
{
if (
// condition 1
&& // condition 2
) {
unset($myArray[$i]);
$i++;
}
}
}
}
$temp = $myArray;
for ($i = 0; $i <= count($myArray); $i++)
{
for ($j = $i + 1; $j <= count($myArray); $j++)
{
if (
// condition 1
&& // condition 2
)
{
unset($temp[$i]);
$i++;
}
}
}
print_r($temp);
Your result is in $temp. So here indexes wont get hampered, you actually are applying all operation on $temp and normally traversing $myArray.
To be honest, I do not know why nobody has yet advise to use nested foreach, since you all noticed there was a problem with array size.
foreach ($numbers as $number_horizontal_parsing) {
foreach ($numbers as $number_vertical_parsing) {
if ($number_horizontal_parsing != $number_vertical_parsing) {
//do your stuff in your case it seems you want to compare both variables
}
}
}
I am coding LCS(longest common subsequence) in php program by using recursive approach. I have the following code:
<?php
$lcsTbl = array(array(128),array(128));
$backTracks = array(array(128),array(128));
$str1 = 'asdvadsdad';
$str2 = 'asdasdadasda';
$len1 = strlen($str1);
$len2 = strlen($str2);
echo LCS_Length($lcsTbl, $backTracks, $str1, $str2, $len1, $len2); //longest common sub sequence
echo '<br/>';
function LCS_Length(&$LCS_Length_Table, &$B, &$s1, &$s2, &$m, &$n)
{
//reset the 2 cols in the table
for($i=1; $i < $m; $i++) $LCS_Length_Table[$i][0]=0;
for($j=0; $j < $n; $j++) $LCS_Length_Table[0][$j]=0;
for ($i=1; $i <= $m; $i++) {
for ($j=1; $j <= $n; $j++) {
if ($s1[$i-1]==$s2[$j-1])
{ $LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i-1][$j-1] + 1; $B[$i][$j] = '\\';}
else if ($LCS_Length_Table[$i-1][$j] >= $LCS_Length_Table[$i][$j-1])
{ $LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i-1][$j]; $B[$i][$j] = '|';}
else
{ $LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i][$j-1]; $B[$i][$j] = '-';}
}
}
return $LCS_Length_Table[$m][$n];
}
To print the LCS, I call the following function:
$x = str_split($str1);
echo lcs_print($backTracks, $str1, $len1, $len2); //print longest common sub sequence
function lcs_print(&$B, &$x, &$i, &$j)
{
if( $i == 0 || $j == 0 )
return;
if( $B[$i][$j] == '\\' ) {
echo $x[$i-1];
lcs_print( $B, $x, $i = $i-1, $j = $j-1 );
} else if( $B[$i][$j] == '|' ) {
lcs_print( $B, $x, $i = $i-1, $j );
} else {
lcs_print( $B, $x, $i, $j = $j-1 );
}
}
?>
This code counts the total lengthof LCS correctly but gives "Notice: Undefined offset: -1" on every call of this line in print function echo $x[$i-1]; and prints nothing. I have tried almost everything to split the string of $str1 and then pass it to function, but nothing works. It does not print LCS string because something is wrong with this line of code echo $x[$i-1]; which I am unable to get. Please help.
Note: The pseudocode of the above code has been taken from book of Thomas H. Cormen, "Introduction to Algorithms 3rd Edition". I am writing it into PHP with the intention of extending it so that it can print LCS of more than two strings. I'll appreciate if anyone shares idea of How can I extend this code so that it can print LCS of an array with multiple strings like $array{'sdsad','asddaw','asd',...n}. Later, I intend to convert the entire program into MATLAB.
There are issues in your LCS_length
1.if ($s1[$i-1]==$s2[$j-1]) ,it should have been if ($s1[$i]==$s2[$j])
2.your boundary condition ($j=0; $j < $n) is unclear, you need to include this upperbound
and you are trying to print it calling this lcs_print($backTracks, $str1, $len1, $len2).
It should have been ($j=0;$j<=n;$j++)
I think these changes will solve the problem.
I haven't done coding in PHP so can't say about the syntaxes.
I have solved the error: I have placed echo $x[$i-1]; before lcs_print( $B, $x, $i = $i-1, $j = $j-1 ); in lcs_print function, all is working fine now.
I'm trying to align strings in PHP using Levenshtein distance algorithm. The problem is that my back tracing code does not work properly for all cases. For example when the second array has inserted lines at the beginning. Then the back tracing will only go as far as when i=0.
How to properly implement back tracing for Levenshtein distance?
Levenshtein distance, $s and $t are arrays of strings (rows)
function match_rows($s, $t)
{
$m = count($s);
$n = count($t);
for($i = 0; $i <= $m; $i++) $d[$i][0] = $i;
for($j = 0; $j <= $n; $j++) $d[0][$j] = $j;
for($i = 1; $i <= $m; $i++)
{
for($j = 1; $j <= $n; $j++)
{
if($s[$i-1] == $t[$j-1])
{
$d[$i][$j] = $d[$i-1][$j-1];
}
else
{
$d[$i][$j] = min($d[$i-1][$j], $d[$i][$j-1], $d[$i-1][$j-1]) + 1;
}
}
}
// backtrace
$i = $m;
$j = $n;
while($i > 0 && $j > 0)
{
$min = min($d[$i-1][$j], $d[$i][$j-1], $d[$i-1][$j-1]);
switch($min)
{
// equal or substitution
case($d[$i-1][$j-1]):
if($d[$i][$j] != $d[$i-1][$j-1])
{
// substitution
$sub['i'][] = $i;
$sub['j'][] = $j;
}
$i = $i - 1;
$j = $j - 1;
break;
// insertion
case($d[$i][$j-1]):
$ins[] = $j;
$j = $j - 1;
break;
// deletion
case($d[$i-1][$j]):
$del[] = $i;
$i = $i - 1;
break;
}
}
This is not to be nit-picky, but to help you find the answers you want (and improve your implementation).
The algorithm you are using is the Wagner-Fischer algorithm, not the Levenshtein algorithm. Also, Levenshtein distance is not use to align strings. It is strictly a distance measurement.
There are two types of alignment: global and local. Global alignment is used to minimize the distance between two entire strings. Example: global align "RACE" on "REACH", you get "RxACx". The x's are gaps.
In general, this is the Needleman-Wunsch algorithm, which is very similar to the Wagner-Fischer algorithm. Local alignment finds a substring in a long string and minimizes the difference between a short string and a the substring of the long string.
Example: local align "BELL" on "UMBRELLA" and you get "BxELL" aligned on "BRELL". It is the Smith-Waterman algorithm which, again, is very similar to the Wagner-Fischer algorithm.
I hope that this is helpful in allowing you to better define the exact kind of alignment you want.
I think your bug is exactly what you say in your question that it is: you stop as soon as i==0, instead of going all the way to i==0 && j==0. Simply replace this condition:
while($i > 0 && $j > 0)
with
while ($i > 0 || $j > 0)
and you're halfway to your solution. The tricky bit is that if $i==0, then it's incorrect to use the array index $i-1 in the loop body. So you'll also have to change the body of the loop to something more like
while ($i || $j) {
$min = $d[$i][$j]; // or INT_MAX or something
if ($i && $j && $min > $d[$i-1][$j-1]) {
$newi = $i-1;
$newj = $j-1;
$min = $d[$newi][$newj];
}
if ($i && $min > $d[$i-1][$j]) {
$newi = $i-1;
$newj = $j;
$min = $d[$newi][$newj];
}
if ($j && $min > $d[$i][$j-1]) {
$newi = $i;
$newj = $j-1;
$min = $d[$newi][$newj];
}
// What sort of transformation is this?
if ($newi == $i && $newj == $j) {
assert(false); // should never happen
} else if ($newi == $i) {
// insertion
$ins[] = $j;
} else if ($newj == $j) {
// deletion
$del[] = $i;
} else if ($d[$i][$j] != $d[$newi][$newj]) {
// substitution
$sub['i'][] = $i;
$sub['j'][] = $j;
} else {
// identity
}
assert($newi >= 0); assert($newj >= 0);
$i = $newi;
$j = $newj;
}
I have this simple quicksort function (I got it from uncle "G")
function quicksort( &$list, $l , $r ) {
$i = $l;
$j = $r;
$tmp = $list[(int)( ($l+$r)/2 )];
do {
while( $list[$i] < $tmp )
$i++;
while( $tmp < $list[$j] )
$j--;
if( $i <= $j ) {
$w = $list[$i];
$list[$i] = $list[$j];
$list[$j] = $w;
//_swp($list[$i],$list[$j]);
$i++;
$j--;
}
}while( $i <= $j );
if( $l < $j )
quicksort($list, $l, $j);
if( $i < $r )
quicksort($list, $i, $r);
return $list;
}
And I have this little function to swap two variables.
function _swp(&$a,&$b){
$a=$a+$b;
$b=$a-$b;
$a=$a-$b;
}
How come I can't use _swp($a,$b) in quicksort function instead of this lines?
$w = $list[$i];
$list[$i] = $list[$j];
$list[$j] = $w;
If I comment out these 3 lines of code and enter call to _swp function I got bad results...
Please explain.
Best regards
the unexpected behavior is probably the "random" occurence of zeros in the sorted list. This happens because there is a special case while swapping:
if( $i <= $j ) {
// swapping here using references!
_swp($list[$i],$list[$j]);
$i++;
$j--;
}
The problem is found directly in the condition for swapping itself: if $i==$j then there are two references to the same variable. Thus calling _swp($list[$i],$list[$j]); will firstly add both variables $a = $a + $b. Considering $a and $b actually access the same variable content, $a and $b will then have the same value. In the next step $b = $a - $b will then be zero as $a is equal to $b. The third operation will leave the result to 0.
An easy solution for this is inserting another condition:
if( $i <= $j ) {
// ensure $i to be truly smaller than $j
if( $i < $j ) {
_swp($list[$i],$list[$j]);
}
$i++;
$j--;
}
I hope this will help you.
Cheers,
Fabian