I have the following code:
<?php
class Node{
public $left,$right;
public $data;
function __construct($data)
{
$this->left=$this->right=null;
$this->data = $data;
}
}
class Solution{
public function insert($root,$data){
if($root==null){
return new Node($data);
}
else{
if($data<=$root->data){
$cur=$this->insert($root->left,$data);
$root->left=$cur;
}
else{
$cur=$this->insert($root->right,$data);
$root->right=$cur;
}
return $root;
}
}
public function getHeight($root) {
$heightLeft = 0;
$heightRight = 0;
if ($root->left != null) {
$heightLeft = getHeight($root->left) + 1;
}
if ($root->right != null) {
$heightRight = getHeight($root->right) + 1;
}
echo "heightRigh is $heightRight\n";
echo "heightLeft is $heightLeft\n";
$ans = ($heightLeft > $heightRight ? $heightLeft : $heightRight);
return $ans;
}
}//End of Solution
$myTree=new Solution();
$root=null;
$T=intval(fgets(STDIN));
while($T-->0){
$data=intval(fgets(STDIN));
$root=$myTree->insert($root,$data);
}
$height=$myTree->getHeight($root);
echo $height;
?>
When I run it with the inputs
1
1
it gives the correct results.
But when I run it with the inputs
2
1
2
I get the error:
PHP Fatal error: Call to undefined function getHeight() in C:\git\phpStudy\CallingAFunction.php on line 36
Fatal error: Call to undefined function getHeight() in C:\git\phpStudy\CallingAFunction.php on line 36
I am new to php and can't figure out what I am doing wrong. Thank you.
The answer is very easy. In short your problem is this:
a) leads to fatal error as described:
class Solution{
public function getHeight($a) {
if($a==true) {
return getHeight(false);
}
return "hello";
}
}
$a = new Solution();
echo $a->getHeight(true);
b) works:
class Solution{
public function getHeight($a) {
if($a==true) {
return $this->getHeight(false);
}
return "hello";
}
}
$a = new Solution();
echo $a->getHeight(true);
You need to reference to the class if you want to call a function inside the class. Use $this->.
In line 36 you have a recursive function call to get height. The function is not found. Correct solution is therefore:
<?php
class Node{
public $left,$right;
public $data;
function __construct($data)
{
$this->left=$this->right=null;
$this->data = $data;
}
}
class Solution{
public function insert($root,$data){
if($root==null){
return new Node($data);
}
else{
if($data<=$root->data){
$cur=$this->insert($root->left,$data);
$root->left=$cur;
}
else{
$cur=$this->insert($root->right,$data);
$root->right=$cur;
}
return $root;
}
}
public function getHeight($root) {
$heightLeft = 0;
$heightRight = 0;
if ($root->left != null) {
$heightLeft = $this->getHeight($root->left) + 1;
}
if ($root->right != null) {
$heightRight = $this->getHeight($root->right) + 1;
}
echo "heightRigh is $heightRight\n";
echo "heightLeft is $heightLeft\n";
$ans = ($heightLeft > $heightRight ? $heightLeft : $heightRight);
return $ans;
}
}//End of Solution
$myTree=new Solution();
$root=null;
$T=intval(fgets(STDIN));
while($T-->0){
$data=intval(fgets(STDIN));
$root=$myTree->insert($root,$data);
}
$height=$myTree->getHeight($root);
echo $height;
?>
Related
I'm trying to implement a skip list in PHP using the pseudocode from http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Map/skip-list-impl.html. I managed to get it working fine in java, but not in PHP. My put method is always returning null, and therefore, my get method too returns null.
I don't quite understand where I'm going wrong, so I'd appreciate any assistance!
<?php
interface SkipListEntry {
public function getPrev();
public function getNext();
public function getAbove();
public function getBelow();
public function getKey();
public function getValue();
public function setValue($v);
public function setPrev($v);
public function setNext($v);
public function setAbove($v);
public function setBelow($v);
public function hasPrev();
public function hasNext();
public function hasAbove();
public function hasBelow();
}
class SkipListNode implements SkipListEntry {
private $prev;
private $next;
private $above;
private $below;
private $key;
private $value;
public static $posInf = "+oo";
public static $negInf = "-oo";
function __construct($a, $b) {
$this->key = $a;
$this->value = $b;
}
public function getPrev(){
return $this->prev;
}
public function getNext(){
return $this->next;
}
public function getAbove(){
return $this->above;
}
public function getBelow(){
return $this->below;
}
public function getKey(){
return $this->key;
}
public function getValue(){
return $this->value;
}
public function setValue($n){
$this->value = $n;
}
public function setPrev($n) {
$this->prev = $n;
}
public function setNext($n) {
$this->next = $n;
}
public function setAbove($n) {
$this->above = $n;
}
public function setBelow($n) {
$this->below = $n;
}
public function hasPrev(){
return !is_null($this->prev);
}
public function hasNext(){
return !is_null($this->next);
}
public function hasAbove(){
return !is_null($this->above);
}
public function hasBelow(){
return !is_null($this->below);
}
}
class SkipList{
private $topLeft;
private $topRight;
private $height = 0;
private $totalEntries = 0;
private $head;
function __construct(){
$this->topLeft = new SkipListNode(SkipListNode::$negInf, null);
$this->topRight = new SkipListNode(SkipListNode::$posInf, null);
$this->topLeft->setNext($this->topRight);
$this->topRight->setPrev($this->topLeft);
$this->head = $this->topLeft;
}
public function size() {
return $this->totalEntries;
}
public function isEmpty(){
return $this->totalEntries == 0;
}
public function search($key){
$p = $this->head;
while (true) {
while (!$p->getNext()->getKey() == SkipListNode::$posInf
&& strcmp($p->getNext()->getKey(), $key) <= 0) {
$p = $p->getNext();
}
if ($p->hasBelow()){
$p = $p->getBelow();
}
else {
break;
}
}
return $p;
}
public function put($key, $value){
$searchElement = $this->search($key);
if ($key == $searchElement->getKey()){
$oldValue = $searchElement->getValue();
$searchElement->setValue($value);
return $oldValue;
}
$newEntry = new SkipListNode($key, $value);
$newEntry->setPrev($searchElement);
$newEntry->setNext($searchElement->getNext());
$searchElement->getNext()->setPrev($newEntry);
$searchElement->setNext($newEntry);
$currentHeight = 0;
for ($j = 1; $j <= $this->coinFlip(); $j ++){
if ($currentHeight >= $this->height){
$this->createAdditionalLayer();
}
while (is_null($searchElement->getAbove())){
$searchElement = $searchElement->getprev();
}
$searchElement = $searchElement->getAbove();
$aboveElement = new SkipListNode($key, null);
$aboveElement->setPrev($searchElement);
$aboveElement->setNext($searchElement->getNext());
$aboveElement->setBelow($newEntry);
$searchElement->getNext()->setPrev($aboveElement);
$searchElement->setNext($aboveElement);
$newEntry->setAbove($aboveElement);
$newEntry = $aboveElement;
$currentHeight ++;
}
$this->totalEntries ++;
return null;
}
public function get($key){
$p = $this->search($key);
if ($p->getKey() == $key){
return $p->getValue();
}
return null;
}
private function createAdditionalLayer(){
$newtopLeft = new SkipListNode(SkipListNode::$negInf, null);
$newtopRight = new SkipListNode(SkipListNode::$posInf, null);
$newtopLeft->setNext($newtopRight);
$newtopLeft->setBelow($this->head);
$newtopRight->setPrev($newtopLeft);
$this->head->setAbove($newtopLeft);
$this->head = $newtopLeft;
$this->height ++;
}
private function coinFlip(){
$total = 0;
$current = -1;
while ($current != 1){
$current = rand(0,1);
$total ++;
}
return $total;
}
}
// test
$a = new SkipList();
var_dump($a->put("a", "b"));
var_dump($a->put("a", "c")); // should return c (returns null)
var_dump($a->size()); // should return 1 (returns 2)
var_dump($a->get("a")); // should return c, (returns null)
Thank you!
I found some problems in a search function:
please change your code with this and try:
public function search($key){
$p = $this->head;
while (true) {
while ($p->getNext()->getKey() != SkipListNode::$posInf
&& strcmp($p->getNext()->getKey(), $key) == 0) {
$p = $p->getNext();
}
if ($p->hasBelow()){
$p = $p->getBelow();
}
else {
break;
}
}
return $p;
}
The result is:
var_dump($a->put("a", "b"));
var_dump($a->put("a", "c")); string 'b',
var_dump($a->size()); int 1,
var_dump($a->get("a")); string 'c'
Hy,
i started learning PHP and i created a simple MVC Style Codebase.
The Script just generates a random number and displays this numer. I also write a function to display the number shown before but it does not work. The value is empty. Can you help me out, i have no clue whats wrong and there is no php error thrown.
view.php
<?php
class View
{
private $model;
private $view;
public function __construct()
{
$this->model = new Model();
}
public function output()
{
echo 'Current Entry: ';
echo $this->model->getData();
echo '<br />';
echo 'Update';
echo '<br />';
echo 'Last';
}
public function getModel()
{
return $this->model;
}
}
controller.php
<?php
class Controller
{
private $model;
private $view;
public function __construct($view)
{
$this->view = $view;
$this->model = $this->view->getModel();
}
public function get($request)
{
if (isset($request['action']))
{
if ($request['action'] === 'update')
{
for ($i = 0; $i<6; $i++)
{
$a .= mt_rand(0,9);
}
$this->model->setData($a);
}
elseif ($request['action'] === 'preview')
{
$this->model->setLast();
}
else
{
$this->model->setData('Wrong Action');
}
}
else
{
$this->model->setData('Bad Request');
}
}
}
model.php
<?php
class Model
{
private $data;
private $last;
public function __construct()
{
$this->data = 'Default';
}
public function setData($set)
{
if ( ! (($set == 'Wrong Action') && ($set == 'Bad Request')))
{
$this->last = $this->data;
}
$this->data = $set;
}
public function getData()
{
return $this->data;
}
public function setLast()
{
$this->data = $this->last;
}
public function getLast()
{
return $this->last;
}
}
index.php
<?php
require_once 'controller.php';
require_once 'view.php';
require_once 'model.php';
$view = new View();
$controller = new Controller($view);
if (isset($_GET) && !empty($_GET)) {
$controller->get($_GET);
}
$view->output();
Are there any other, bad mistakes in the Script?
Any input very welcome! :)
The problem with your code is that PHP does not preserve variable values between requests, therefore, when you set your $model->last value here:
$this->last = $this->data;
It gets reset on your next request.
You may want to store $last value in a session or a cookie instead. Something like:
$_SESSION['last'] = $this->data;
And then when you are instantiating your model you could initialize it with a value stored in a session if available:
index.php - add session_start() at the beginning
model.php:
public function __construct()
{
$this->data = isset($_SESSION['last']) ? $_SESSION['last'] : 'Default';
}
public function setData($set)
{
$this->data = $set;
if ( ! (($set == 'Wrong Action') && ($set == 'Bad Request')))
{
$_SESSION['last'] = $this->data;
}
}
controller.php
elseif ($request['action'] === 'preview')
{
//Remove this
//$this->model->setLast();
}
<?php
class Timer {
static private $s;
function __construct()
{
self::$s = self::getmicrotime();
}
static public function Start()
{
self::$s = self::getmicrotime();
}
static public function Fetch($decimalPlaces = 6)
{
return number_format((self::getmicrotime() - self::$s), $decimalPlaces);
}
static public function getmicrotime()
{
return array_sum(explode(' ', microtime()));
}
}
class T extends Thread {
public function run() {
test();
}
}
function test()
{
$n = 0;
for($i=1;$i<9999999;$i++)
{
$n+=$i;
}
echo '#';
}
//+++++++++++++++++++++++START DEMO ++++++++++++++++++++++++++
Timer::Start();
//DEMO1,TIME:3.679208 second(s).
$ts = array();
while (count($ts)<10) {
$t = new T();
$t->start();
$ts[]=$t;
}
$ts = array();
//DEMO2,TIME:6.876037 second(s).
/* for($k=0;$k<10;$k++)
{
$t = new T();
$t->start();
} */
echo '<br />Processed in '.Timer::Fetch().' second(s).';
?>
I am reading http://pthreads.org/ on the topic of pthreads and i have this questions,I want to test php multithreading ,but when i use for to create multithreading,but it is not the result I want.
In fact the DEMO1 is correct.
But why the second DEMO elapsed_time 6.876037 second ?
DEMO2 why canot use for to create multithreading ?
this is my code for creating a list of data elements !
in this below line mentioned there are two error(on the same line)
1)Notice: Undefined offset: 0
2)Fatal error: Call to a member function display() on a non-object
<?php
class data
{
public $num;
public $Char;
function __construct()
{
$this->num= "null";
$this->Char= "New Char";
}
public function setInt($int)
{
$this->num=$int;
}
public function setChar($char)
{
$this->Char= $char;
}
public function getInt()
{
return $this->num;
}
public function getChar()
{
return $this->Char;
}
public function display()
{
echo $this->num;
echo $this->Char;
}
}
class linklist extends data
{
public $DATA;
private $list;
private $count;
function __construct()
{
$DATA= new data();
$list= array();
$count=0;
}
function addData(data $d)
{
$this->list[$this->count]= $d;
$this-> count++;
}
function displayy()
{
$d= new data();
$i=0;
for($i;$i<=$this->count; $i++)
{
$this->list[$i]->display(); //** line with error *** //
}
}
}
?>
<!DOCTYPE html>
<html>
<body>
<?php
$d= new data();
//$d->display();
//$Name= $_POST['fname'];
//$Age = $_POST['age'];
$d->setInt("1");
$d->setChar("Ashad");
//$d->display();
$d1= new Data();
$d1->setInt("2");
$d1->setChar("shahrukh");
$list = new linklist();
$list-> addData($d);
$list->addData($d1);
$list->displayy();
?>
</body>
</html>
The constructor of linklist should be:
function __construct()
{
$this->DATA= new data();
$this->list= array();
$this->count=0;
}
You have been missing the $this
Also note the comment of #N.B. :
for($i; $i <= $this->count; $i++)
should be
for($i = 0; $i < $this->count; $i++)
For some reason I cant run the change() function and everything after it stops. I try with $this->change() but the effect is the same. If I run the function in a php file its working and the num is changing.
class Test extends CI_Controller {
function __construct(){
parent::__construct();
}
public function home(){
$num = 1;
change($num);
function change($num,$rand=false){
echo 'inside function'; // this is not shown
if($num < 4) {
$rand = rand(1,9);
$num = $num.$rand;
change($num,$rand);
} else {
echo $num;
}
}
echo 'done'; // this is not shown
}
}
You will probably be better off calling a private or public function to process data ( or for more complex/involved processes a library ).
ie
class Test extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
public function home()
{
$num = 1;
echo $this->_change($num);
echo 'done'; // this is not shown
}
// private or public is w/o the underscore
// its better to use private so that CI doesn't route to this function
private function _change($num, $rand = FALSE)
{
if($num < 4) {
$rand = rand(1,9);
$num = $num + $rand;
$this->_change($num,$rand);
} else {
return $num;
}
}
}
lol, you are trying to write function inside function.
try running your class with this code
class Test extends CI_Controller {
function __construct(){
parent::__construct();
}
public function home(){
$num = 1;
$this->change($num);
echo 'done'; // this is not shown
}
public function change($num,$rand=false){
echo 'inside function'; // this is not shown
if($num < 4) {
$rand = rand(1,9);
$num = $num.$rand;
change($num,$rand);
} else {
echo $num;
}
}
}