warning occuring in php word occurence - php

I have written the following code to count the number of string occurrences in a given file.
PHP
<?php
$p = fopen("g.txt", "r");
$q = fread($p, filesize("g.txt"));
$t = explode(" ", $q);
$m = explode(" ", $q);
$i = 0;
$j = 0;
$r = 0;
$count = 0;
$c = count($t);
$d = array();
echo "count of".
"<br/>";
for ($i = 0; $i < $c; $i++) {
for ($j = $i; $j < $c; $j++) {
if ($t[$i] == $t[$j]) {
$count = $count + 1;
}
}
for ($r = $i + 1; $r < $c; $r++) {
if ($t[$i] == $t[$r])
unset($t[$r]);
}
echo $t[$i].
"=".$count.
"<br/>";
$count = 0;
}
?>
I am getting a notice of undefined offset on line numbers 17 and 24, though my output is coming out to be correct. Can you please help me in rectifying the above problem?

The problem is that you are deleting items from the array $t. You saved the count in $c, but the actual count will change by your last inner loop.
Even if you replace $c by count($t) everywhere, it will go wrong, because the last loop should be in reverse order, otherwise you skip items. For instance if you have the list 'a', 'b', 'c'. then when you delete 'b' and increment $r, you will not check 'c' at all.
So, if I fix those things, your code becomes as below. Although I didn't really check it for other issues. Frankly, I don't really get what is should do. ;-)
<?php
$p=fopen("g.txt","r");
$q=fread($p,filesize("g.txt"));
$t=explode(" ",$q);
$m=explode(" ",$q);
$i=0;
$j=0;
$r=0;
$count=0;
$d=array();
echo "count of"."<br/>";
for($i=0; $i<count($t); $i++)
{
for($j=$i; $j<count($t); $j++)
{
if($t[$i]==$t[$j])
{
$count=$count+1;
}
}
for($r=count($t) - 1; $r > $i; $r--)
{
if($t[$i]==$t[$r])
unset($t[$r]);
}
echo $t[$i]."=".$count."<br/>";
$count=0;
}
?>
In conclusion, you should do more tests. If the outcome of this script was okay, then it was by accident.

Related

Why can't I use a function to simplify my "for loops"

I build a webpage to crack simple MD5 hash of a four digit pin for fun. The method I used was basically try all combination and check against the MD5 value the user has entered. Below is the PHP code I created to accomplish the goal.
Debug Output:
<?php
$answer = "PIN not found";
if (isset($_GET['md5'])) {
$txt = 'abcdefjhig';
$time_pre = microtime(TRUE);
$value = $_GET['md5'];
$show = 15;
for ($i = 0; $i <= 9; $i++) {
$first = $i;
for ($j = 0; $j <= 9; $j++) {
$second = $j;
for ($k = 0; $k <= 9; $k++) {
$third = $k;
for ($x = 0; $x <= 9; $x++) {
$fourth = $x;
$whole = $first . $second . $third . $fourth;
$check = hash('md5', $whole);
if ($check == $value) {
$answer = $whole;
echo "The pin is $answer";
}
if ($show > 0) {
print"$check $whole \n";
$show = $show - 1;
}
}
}
}
}
echo "\n";
$time_post = microtime(TRUE);
print "Elapsed time:";
print $time_post - $time_pre;
}
?>
Notice that in the middle there are four very similar for loops,I tried to simplify this by using functions, but it just returns one four digit number which is 9999 instead of all of them.
Below is the function I created:
function construct($input){
for($i=0; $i<=9, $i++){
$input=$i;
}
return $input
}
Then I tried to call this function for four times to form all of the four digit numbers but it just gives me 9999. Can anybody help? Thanks a lot.
Try this:
for ($i=0; $i<=9999 ; $i++) {
$whole = sprintf('%04d', $i);
$check=hash('md5', $whole);
if($check==$value){
$answer=$whole;
echo "The pin is $answer";
break; //remove this if you do not want to break the loop here
}
if ($show>0) {
print"$check $whole \n";
$show=$show-1;
}
}
You're using numbers from 0 to 9999, so why just loop through those numbers? You can add zero's by using str_pad() like so:
for ($i = 0; $i <= 9999; $i++) {
$whole = str_pad($i, 4, '0', STR_PAD_LEFT);
}
Also I'd like to mention that you really should think about better formatting of your code, especially indentation

How to return array in php?

How to return array in php ? Actually I want to return whole value of $x[] insted of last index of $x[]. Please help me...
<?php
function top() {
require './php/connection.php';
$sql = "SELECT * FROM tbl_add";
$query = mysqli_query($connect, $sql);
$n = 0;
while ($result = mysqli_fetch_assoc($query)) {
$a[$n] = $result['add_id'];
$n = $n + 1;
}
$n = $n - 1;
for ($j = 0; $j < $n; $j++) {
for ($i = 0; $i < $n - 1 - $j; $i++) {
if ($a[$i] > $a[$i + 1]) {
$tmp = $a[$i];
$a[$i] = $a[$i + 1];
$a[$i + 1] = $tmp;
}
}
}
for ($i = 0; $i <= $n; $i++) {
echo $a[$i] . '<br>';
}
$j = 1;
for ($i = 0; $i <= 5; $i++) {
$r = $a[$i];
$sql = "SELECT * FROM tbl_add WHERE add_id='$r'";
$query = mysqli_query($connect, $sql);
$result = mysqli_fetch_assoc($query);
if ($result) {
$x[] = $result['mail'];
return $x[];
}
}
}
?>
return $x[]; is invalid syntax.
In expression $x[] = $result['mail'];, $x[] doesn't mean "the last element of $x". It is just a courtesy of PHP that spares the programmer of writing $x[count($x)]1 instead.
Returning an array is as easy as return $x; (given $x is an array).
Btw, there is no place in your code where $x is initialized as array. You just add values to some variable that doesn't exist, using the array syntax. PHP helps you and creates an array first and stores it in the $x variable but this practice is strongly discouraged. You should add $x = array(); somewhere before you use $x for the first time (outside the loop, of course). For example, you can put it before the line for ($i = 0; $i <= 5; $i++) {.
`
1 This statement is not entirely correct. However, if the values are added to the array using only the $x[] = ... syntax (as it happens in the posted code) then it is correct.
You have to return $x
Then when you call this function $data = top();
Now you get return data of function top to variable name data
// the code below will return $x as it is, independent of what it is. Array, integer, string etc..
Return $x;
// if you need to return two values use:
Return array($x, $y);
// again bit variables are returned as they are.
To call the function and get the values/array use:
$array = top();
Var_dump($array); //should be $x from your function

How to calculate Diagonal difference in PHP?

I have a N*N Matrix.Now i want to know the diagonal difference of this Matrix.What will be the best approach of this solution?
I am trying with given approach:
Such as it is 3*3 Matrix say it is:
11 15 85
66 72 21
14 21 47
the diagonal simple formula will be:
firstD= (11+72+47) = 130
secondD = (85+72+14)= 171
diagonalDiff = |firstD - secondD| = |130-171| = 41
If I count every row such as first to find out firstD (First row's first value + Sec row's Sec value + Third row's third value+..).This is my thinking.
Can anyone tell me best approaches?
Try this:
$arr = array(
array(11, 15, 85),
array(66, 72, 21),
array(14, 21, 47),
);
$arrDiag = count($arr);
$firstD = 0;
$secondD = 0;
$i = 0;
for($j = 0; $j < $arrDiag; $j++){
$firstD += $arr[$i++][$j];
$secondD += $arr[$arrDiag - $i][$j];
}
echo abs($firstD - $secondD);//41
Model your matrix with a multi-dimensional array and iterate through it. The easiest way should be the following:
<?
$matrix = array(array(1,2,3),array(4,5,6),array(7,8,9)); //Insert or define your matrix here..
$n = count($matrix); //Size of matrix, thanks to VolkerK
$firstD = 0;
$lastD = 0;
for($i = 0; $i < $n; $i++){
$firstD += $matrix[$i][$i];
$lastD += $matrix[$i][$n-$i-1];
}
echo $firstD."\n";
echo $lastD;
Here is a pseudo code for your problem using one simple loop:
// $array - predefined 2 dimentional array with $N rows and $N columns
$result = 0;
for ($i=0;$i<$N;$i++) {
$result += ($array[$i,$i] - &array[$i,$N-$i-1]);
}
return echo abs($result);
that way you can do the calculation in one pass, and do a diff between two elements in each row insead of calculation the sum of each diagonal
Try this:
function diagonalDifference($arr) {
$left = 0;
$right = 0;
$i = 0;
foreach($arr as $ar){
$left+= $ar[0+$i];
$right+= $ar[count($ar) - (1+$i)];
$i++;
}
return abs($left - $right);
}
Try this
$result=0;
for($i=0;$i<=count($arr)-1;$i++){
$result= $result+($arr[$i][$i])-($arr[(count($arr)-1-$i)] [$i]);
}
return abs($result);
This is the code you need:
$first = 0;
$second = 0;
for($i = 0; $i < N; $i++) {
for($j = 0; $j < N; $j++) {
if($i == $j) {
$first += $matrix[$i][$j];
} else if($i + $j == N) {
$second += $matrix[$i][$j];
}
}
}
$diagonalDiff = abs($first - $second);
Where $matrix is a N*N array
Just using the function array_reduce:
function diagonalDifference($arr) {
$i = 0;
$n = count($arr);
return abs(array_reduce($arr,
function ($c, $str) use (&$i, $n ) {
$i++;
return $c + $str[$i-1] - $str[$n-$i];
}, 0));
}
demo
you can try this :
$first_diag=$second_diag=0;
$matrix=array(array(11,15,85),array(66,72,21),array(14,21,47));
foreach($matrix as $index=>$sub_array){
$first_diag +=$sub_array[$index];
$second_diag +=$sub_array[count($matrix)-1-$index];
}
print abs ($first_diag-$second_diag);
For one you can use a matrix library like Math_Matrix. But if this is the only operation you are gona need then it's best to write a generalized function for this using the same method you quoted yourself.
function diagonalDiff($n){
$firstD = 0;
$secondD = 0;
for($i=0;$i<$n;$i++){
for($j=0;$j<$n;$j++){
if($i == $j) {
$first += $matrix[$i][$j];
} else if($i + $j == $n) {
$secondD += $matrix[$i][$j];
}
}
}
return abs($firstD-$secondD);
}
Should give you the answer you need for a matrix of a given size $n. (Only square Matrixes ofcourse :) )
Another better solution and it's easy to understand:
<?php
$arr = array(
array(11, 15, 85),
array(66, 72, 21),
array(14, 21, 47),
);
$arrDiag = count($arr);
$firstD = 0;
$secondD = 0;
$i = 0;
for($j = 0; $j < $arrDiag; $j++){
$i++;
$firstD += $arr[$j][$j];
$secondD += $arr[$arrDiag - $i][$j];
}
echo abs($firstD - $secondD);
?>
DEMO
Recently solved this question in Hacker Rank.
<?php
$m=array(array(3,4,-1,11,2),
array(-3,2,1,6,9),
array(3,4,6,5,-2),
array(1,9,9,7,-3),
array(12,9,16,7,-3));
echo count($m)."<br>";
$i=0;
$j=0;
$ek=0;
$k=0;
$n=1;
$es=count($m)-1;
for($i=0;$i<count($m);$i++)
{
for($j=0;$j<count($m);$j++)
{
echo $m[$i][$j]." ";
}
echo "<br>";
}
echo "<br>";
for($k=0;$k<count($m);$k++)
{
for($n=0;$n<count($m);$n++)
{
if($k==$n){
$ek=$ek+$m[$k][$n];
}
}
echo "<br>";
}
echo "<hr>";
$p=0;
for($k=0;$k<count($m);$k++)
{
echo $m[$k][$es-$p]."<br> ";
$p++;
}
?>
Sorry I used different variable names, I had to take this to my vs code.
$b = array(
array(1,2,5),
array(3,4,5),
array(3,4,5)
);
//So for each diag
echo $b[0][0] + $b[1][1] + $b[2][2]; //to sum the first diag
echo $b[0][2] + $b[1][1] + $b[2][0]; //to sum the second diag
//notice the pattern 00, 11, 22 vs 02,11, 20. hence why I have written the function below
function difference($b){
$d1 = 0;
$d2 = 0;
$count = count($b);
for($i=0; $i<$count; $i++){
$d1 += $b[$i][$i];
$d2 += $b[$i][$count-1-$i];
}
return abs($d1 - $d2);
}
I had the same issue, the instructions was given by the site, mislead me. However, I solved it in this way,
$n = count and store the length of input array
//define variables to store first diagonals and second diagonals
$fd = 0;
$sd = 0;
//loop through the 2D array with $i increment
$j = get an array from the main array
//in each iteration
$pd += get the values from the left to the right and add;
$sd += get the values from the right to the left and add;
}
find absolute difference between the sums using built in abs function and return it;
I think this would help someone

PHP: Cannot use [] for reading - but it's not [] but [$counter]

in general I think I understand what the error message means. But in my case, it's a riddle I didn't succeed in solving...
$keywords_all = array();
$count = 0;
for ($z = 0; $z < $num_results; $z++)
{
$keywords_array = explode(",", $row['free_keywords']);
for ($i = 0; $i < count($keywords_array); $i++)
{
if (in_array(strtolower(trim($keywords_array[$i])), $keywords_all))
{
$count++;
}
else
{
echo "<br />".$keywords_array[$i];
$keywords_all[$count] = $keywords_array[$i];
}
}
$row = pg_fetch_array($result);
}
So, what's wrong with that one? The error message pops up in the line
$keywords_all[$count] = $keywords_array[$i];
I have no clue, seems to be alright to me. But guess, it's again a tiny, tiny thing I've neglected... Thanks for any hints!
I was not able to reproduce your error message. I did find a bug in your code though (I am assuming that you are putting all your keywords in the $keywords_all array without any duplicates). So you should not increment $count inside your IF but instead update the $keywords_all count. See below:
if (in_array(strtolower(trim($keywords_array[$i])), $keywords_all)) {
$count = count($keywords_all);
} else {
echo "<br />".$keywords_array[$i];
$keywords_all[$count] = $keywords_array[$i];
$count++;
}
You will increment $count after storing a value to your $keywords_all array.
$keywords_all = array();
$count = 0; // what for you neet this var ?
$myRow = 'keyW1,keyW2,keyW3,keyW2';
// for ($z = 0; $z < $num_results; $z++) // there is no variable $num_results at your code so I've replaced it with constant
for ($z = 0; $z < 1; $z++)
{
// $keywords_array = explode(",", $row['free_keywords']);
$keywords_array = explode(",", $myRow);
// for ($i = 0; $i < count($keywords_array); $i++)
foreach ($keywords_array as $keyword)
{
$keyword = strtolower( trim( $keyword ) ); // some syntax sugar would be nice
if ( !in_array( $keyword, $keywords_all) )
{
echo "<br />".$keyword;
$keywords_all[] = $keyword;
}
}
// $row = pg_fetch_array($result);
}
var_dump($keywords_all);
This code would be better for you i think, but if you just want to get rid of duplicated records
array_uniq( array("1", "1", "2", "1") )
would be better solution for you.

add in loop in multi dimensional array

i am facing a problem
can some one suggest me
for ($i = 1; $i <= 2; $i++) {
$r2 = 0;
for ($t = 1; $t <= 2; $t++) {
echo $r2;
$r2++
}
}
output is 0101;
can i get output 0123 ??? please
if
for ($i = 1; $i <= 3; $i++) {
$r2 = 0;
for ($t = 1; $t <= 3; $t++) {
echo $r2;
$r2++
}
}
output is 010101;
can output 012345678 ??? please
and if
for ($i = 1; $i <= 4; $i++) {
$r2 = 0;
for ($t = 1; $t <= 4; $t++) {
echo $r2;
$r2++
}
}
output is 01010101;
can output 0123456789101112131415 ??? please
i think you understand
thanks
In all of these cases you are initializing $r2=0; in the inner loop. It should be outside the loop.
$r2=0;
for($i=1;$i<=2;$i++){
for($t=1;$t<=2;$t++){
echo $r2;
$r2++
}
}
This would produce "1234".
why are you using two nested for loops ?
why not just use one:
for ($i=0; $i<=15; $i++) echo $i . " ";
Try this:
$r2 = 10;
for($t = 0; $t <= $r2; $t++){
echo $r2;
}
Oh wait.. I get it now, why you have the two nested loops, you want to essentially raise a number to the power of 2 in order to control the number of values output. In that case, what you want is simply this:
// this is the variable you need to change to affect the number of values outputed
$n = 2;
// Square $n
$m = $n * $n;
// Loop $m times
for ($i = 0; $i < $m; $i++) {
echo $i;
}

Categories