SitePoint Sponsor

User Tag List

Results 1 to 16 of 16
  1. #1
    SitePoint Member
    Join Date
    Mar 2004
    Location
    USA
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    1 Thread(s)

    Question Stack and Vector Class

    Hi All,

    I was just messing around with arrays and objects. I built these two classes based on Java's Stack and Vector Classes. The Vector class is not a full conversion, but more of a start. Also this is not a true Vector because it is does not resize on demand like a Java Vector. I just wanted your thoughts on the classes if any. Thanks in advance.

    One question, this might just be preference but, I only allow the storage of other objects. Do you think that this would be more useful if I allowed the storage of Integers or Strings or would these be seperate Objects?

    Stack Class:
    PHP Code:
    <?php
    require_once('Vector.class.php');

    class 
    Stack extends Vector
    {

    //CONSTRUCTOR
        /***
         * <p>Creates an empty Stack.</p>
         * @returns void
         ***/
        
    function Stack()
        {
            
    $this->Vector();
        }
    //END CONSTRUCTOR

    //MANIPULATORS
        /***
         * <p>Pushes an item onto the top of this stack.</p>
         * @param $o Object to push onto the Stack
         * @returns int 1 on success and int 0 on failure
         ***/
        
    function push(&$o)
        {
            
    $blnPushed 0;
            if(
    is_object($o))
            {
                
    $this->arrObjects[] =& $o;
                
    $blnPushed 1;
            }
            return 
    $blnPushed;
        }
        
    /***
         * <p>Removes the object at the top of this stack and returns that 
         * object as the value of this function. </p>
         * @param $o Object to pop off of the end of the Stack
         * @returns obj Object on success and int 0 on failure
         ***/
        
    function pop()
        {
            
    $o 0;
            if(!
    $this->isEmpty())
            {
                
    $o array_pop($this->_getObjects());
            }        
            return 
    $o;
        }
        
    /***
         * <p>Looks at the object at the top of this stack without removing it from the stack.</p>
         * @param $o Object to peek at in the Stack
         * @returns obj Object on success and int 0 on failure
         ***/
        
    function peek()
        {
            
    $o 0;
            if(!
    $this->isEmpty())
            {
                
    $lastElement $this->size() - 1;
                
    $o $this->arrObjects[$lastElement];
            }
            return 
    $o;
        }
        
    /***
         * <p>Returns the 1-based position where an object is in the Stack.</p>
         * @param $str String
         * @returns $intPostition Integer on success and -1 if the item is not in the Stack
         ***/
        
    function search($str)
        {
            
    $intPostition = -1;
            
    $arrTemp =& $this->_getObjects();        
            for(
    $i=0$i $this->Size(); $i++)
            {
                
    //get_class only returns the lowercase name
                
    if(get_class($arrTemp[$i]) == strtolower($str))
                {
                     
    $intPostition $i;
                     break;
                }
            }
            return 
    $intPostition;
        }
    //END MANIPULATORS
    }
    ?>
    Vector Class:
    PHP Code:
    <?php
    class Vector
    {
        
    /***
         * The array of objects
         * @type array
         ***/
        
    var $arrObjects = array();
        
        
    /***
         * The array capacity
         * @type int
         ***/
        
    var $intCapacity;
        
    //CONSTRUCTOR
        
        /***
         * <p>Construct a new Vector</p>
         * @param $intCapacity as int for the size of the Vector
         ***/
        
    function Vector($intCapacity 10)
        {
            
    $this->_setCapacity($intCapacity);
        }
        
    //END CONSTRUCTOR
        
    //MANIPULATORS
        
        /***
         * <p>Adds an object to the Vector if the size of the vector is less than the 
         * capacity <code>[size() < capacity()]</code></p>
         * @param $o the object to add to the vector
         * @returns int 1 on success and int 0 on failure
         ***/
        
    function add(&$o)
        {
            
    $blnAdded 0;
            if (
    $this->size() < $this->Capacity() && is_object($o))
            {
                
    $this->arrObjects[] = $o;
                
    $blnAdded 1;
            }
            return 
    $blnAdded;
        }
        
    /***
         * <p>Inserts the specified element at the specified position in this Vector. 
         * Shifts the element currently at that position (if any) and any subsequent 
         * elements to the right (adds one to their indices).</p>
         * @param $index int the position to add the object
         * @param $o obj the object to add to the vector
         * @returns int 1 on success and int 0 on failure
         ***/
        
    function addAt($index, &$o)
        {
            
    $blnAdded 0;
            if(
               
    $index >= && 
               
    $index <= $this->size() && 
               
    $this->size() < $this->capacity() &&
               
    is_object($o)
               )
            {
                if(
    $index == $this->size())
                {
                    
    $this->arrObjects[$index] = $o;
                    
    $blnAdded 1;
                }
                else 
                {
                    for(
    $i $this->size(); $i $index$i--)
                    {
                        
    $this->arrObjects[$i] = $this->arrObjects[$i-1];
                    }
                    
    $this->arrObjects[$index] = $o;
                    
    $blnAdded 1;
                }
            }
            return 
    $blnAdded;
        }
        
    /***
         * <p>Replaces the element at the specified position ($index) in this Vector with the 
         * specified element ($o).</p>
         * @param $index int the position to set the object
         * @param $o the object to add to the vector
         * @returns int 1 on success and int 0 on failure
         ***/
        
    function set($index, &$o)
        {
            
    $obj=0;
            if(
    $index >= && $index <= $this->size())
            {
                
    $obj $this->arrObjects[$index];
                
    $this->arrObjects[$index] = $o;
            }
            return 
    $obj;
        }
        
    /***
         * <p>Sets the size of this Vector. If the new size is greater than the current size, new null items are 
         * added to the end of the Vector. If the new size is less than the current size, all components at 
         * index newSize and greater are discarded. </p>
         * @param $intNewSize int set the size of the Vector
         * @returns int 1 on success and int 0 on failure
         ***/
        
    function setSize($intNewSize)
        {
            
    $blnSet 0;
            if(
    $intNewSize >= && $intNewSize $this->capacity())
            {        
                if(
    $intNewSize >= $this->size())
                {
                    for(
    $i $this->Size(); $i <= $intNewSize$i++)
                    {
                        
    $this->arrObjects[$i] = null;
                    }
                }
                else 
                {
                    for(
    $i $intNewSize$i <= $this->size(); $i++)
                    {
                        unset(
    $this->arrObjects[$i]);
                    }
                }
            }
            return 
    $blnSet;
        }
        
    /***
         * <p>Trims the capacity of this Vector to be the Vector's current size. If the capacity of this vector 
         * is larger than its current size, then the capacity is changed to equal the size.  An application can 
         * use this to prevent the Vector from growing.</p>
         * @returns void 
         ***/
        
    function trimToSize()
        {
            
    $this->_setCapacity($this->size());
        }
        
    /***
         * <p>Removes the element at the specified position in this Vector. shifts any subsequent elements 
         * to the left (subtracts one from their indices). Returns the element that was removed from the Vector.</p>
         * @param $index int removes the element at the $index in the Vector
         * @returns obj that was removed on success and int 0 on failure
         ***/
        
    function removeAt($index)
        {
            
    $o 0;
            if(!
    $this->isEmpty() && ($this->size() >= $index))
            {
                
    $o $this->arrObjects[$index];
                unset(
    $this->arrObjects[$index]);
                
    $this->arrObjects array_values($this->_getObjects());
            }        
            return 
    $o;
        }
        
    /***
         * <p>Removes all of the elements from this Vector. The Vector will be empty after this call.</p>
         * @returns void
         ***/
        
    function clear()
        {
            
    $this->arrObjects = array();
        }
        
    /***
         * <p>Removes all components from this vector and sets its size to zero.</p>
         * @returns void
         ***/
        
    function removeAllElements()
        {
            
    $this->clear();
        }
        
    /***
         * <p>Returns a copy of this vector.</p>
         * @returns Vector a copy of this Vector
         ***/
        
    function clone()
        {
            return new 
    $this;
        }
        
    /***
         * <p>Returns the current capacity of this Vector.</p>
         * @returns void
         ***/
        
    function capacity()
        {
            return 
    $this->intCapacity;
        }
        
    /***
         * <p>Returns the number of components in this Vector.</p>
         * @returns int
         ***/ 
        
    function size()
        {
            return 
    sizeof($this->arrObjects);    
        }
        
    /***
         * <p>Returns whether the Vector is empty or not.</p>
         * @returns int 1 if the Vector is empty and 0 otherwise
         ***/     
        
    function isEmpty()
        {
            (
    sizeof($this->arrObjects) > 0) ? $blnEmpty 
                                      
    $blnEmpty 1;
            return 
    $blnEmpty;
        } 
        
    /***
         * <p>Returns the first object (the item at index 0) of this Vector.</p>
         * @returns obj on success and 0 on failure
         ***/
        
    function firstElement()
        {
            
    $o 0;
            if(!
    $this->isEmpty())
            {
                
    $o $this->arrObjects[0];
            }
            return 
    $o;
        }
        
    /***
         * <p>Returns the last object (the item at index [size() - 1]) of this Vector.</p>
         * @returns obj on success and 0 on failure
         ***/
        
    function lastElement()
        {
            
    $o 0;
            if(!
    $this->isEmpty())
            {
                
    $lastElement $this->size() - 1;
                
    $o $this->arrObjects[$lastElement];
            }
            return 
    $o;
        }
        
    /***
         * <p>Returns a string representation of this Vector, 
         * containing the String representation of each element. </p>
         * @returns str
         ***/
        
    function toString()
        {
            
    $str="";
            for(
    $i=0$i $this->size(); $i++)
            {
                
    $str .= "Object Name:      " get_class($this->arrObjects[$i]) . "<br>" 
                       
    "Object Position: " $i ",<br>";
            }
            return 
    $str;
        }
    //END MANIPULATORS

    //PRIVATE ACCESSORS
        
    function _getObjects()
        {
            return 
    $this->arrObjects;
        }
        
        function 
    _setCapacity($value)
        {
            
    $this->intCapacity $value;
        }
    //END ACCESSORS
    }
    //end Vector---------------------------------
    ?>
    Please let me know your thoughts good and bad. I am fairly new to php so I just want input.

    Kind regards,

    php
    Last edited by php; Mar 26, 2004 at 20:31.

  2. #2
    SitePoint Wizard Chris82's Avatar
    Join Date
    Mar 2002
    Location
    Osnabrück
    Posts
    1,003
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, you asked for comments and mine are probably a bit on the negative side:

    IMHO, the Java classes Stack and Vector aren't good role models. They wrongly use inheritance. A Stack usually only has "pop", "push" and "empty" as methods. But as a subclass it also has all methods defined in Vector. A better way would be to use composition (using a Vector instance as a member variable in Stack).
    You can enforce a certain type but that's only a minor advantage to me.

    Other than that it is a good start with OOP in PHP. I don't know if you have a Java background but I think that porting directly from Java to PHP is not the best way.

    Anyways, good start and good luck with php.

    I don't want to sound rude but I cannot really see a purpose for a Stack class which does hardly anything more than array_pop and array_push.
    A Vector class could be more useful to manage collections with a capacity restriction, though.

  3. #3
    SitePoint Member
    Join Date
    Mar 2004
    Location
    USA
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    1 Thread(s)
    Thanks for your reply.

    The reason for the Stack class is that when working with Objects the array_push takes the object by Value and not by Reference. So if the Object changes the array never sees it happen. With this method the array is updated, at least that is how I see it to be. Please correct me. Also, another nice option is Peek. We want the object, but don't want to take it off of the Stack.

    Can you please explain why you would use composition in this instance over direct inheritance?

    Kind regards,

    php

  4. #4
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The reason for the Stack class is that when working with Objects the array_push takes the object by Value and not by Reference.
    You can do;

    PHP Code:
    $obj = & SomeClass();

    $array = array();
    $array[] = & $obj// Basicallly the same as array_push 
    In fact I can say I ever use array_push().

  5. #5
    SitePoint Member
    Join Date
    Mar 2004
    Location
    USA
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    1 Thread(s)
    Hi,

    That is infact what I do with my Stack->push();. Except now I see a flaw in how I did it. I just did array[] = $object, which also copied a value of and not a reference of. I have edited in my post above and in my code locally. Thanks HarryF.

    What do you think about the rest. And why would you use composition instead of direct inheritance in this case as Chris82 suggested. I don't see why, but maybe I don't understand something.

    Kind regards,

    php

  6. #6
    SitePoint Guru dagfinn's Avatar
    Join Date
    Jan 2004
    Location
    Oslo, Norway
    Posts
    894
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by HarryF
    You can do;

    PHP Code:
    $obj = & SomeClass();

    $array = array();
    $array[] = & $obj// Basicallly the same as array_push 
    In fact I can say I ever use array_push().
    The difference between assigning to $array[] and using array_push() is that array_push() requires the array to exist already. The code above will work even without

    PHP Code:
    $array = array(); 
    If you try use array_push() without it, you get an error message. $array[] is more convenient, array_push() might conceivably be useful if you really needed to make sure the array exists.
    Dagfinn Reiersĝl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

  7. #7
    Super Ninja Monkey Travis's Avatar
    Join Date
    Dec 2001
    Location
    Sioux City, Iowa
    Posts
    691
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Um, that code won't work without $array = array();. At least it doesn't whenever I try.
    Travis Watkins - Hyperactive Coder
    My Blog: Realist Anew
    Projects: Alacarte - Gnome Menu Editor

  8. #8
    SitePoint Zealot
    Join Date
    Mar 2004
    Location
    New Jersey
    Posts
    140
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Travis
    Um, that code won't work without $array = array();. At least it doesn't whenever I try.
    sure it does; it'll just trigger an E_NOTICE for using $array before it's initialized.

  9. #9
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Still a bug though

    Are there still people who distribute bug prone script nowadays huh?

  10. #10
    SitePoint Wizard Chris82's Avatar
    Join Date
    Mar 2002
    Location
    Osnabrück
    Posts
    1,003
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by php
    Can you please explain why you would use composition in this instance over direct inheritance?

    Kind regards,

    php
    If you extend Stack from Vector, it also inherits all methods defined in Vector and this way a Stack does all what a Vector plus the new added functions.
    However, the "classic stack" (if you can call it this way only has "push", "pop", "empty" and maybe "peek".
    This isn't a big flaw probably more just one in terms of definition of what a Stack should do.

    Regards,
    Christian

  11. #11
    Non-Member coo_t2's Avatar
    Join Date
    Feb 2003
    Location
    Dog Street
    Posts
    1,819
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    PHP Code:
     
     <?php
     
     $obj 
    =& new Test;
     
     
    var_dump($obj);
     
     
    $arr1 = array();
     
    $arr2 = array();
     
     
    array_push($arr1$obj);
     
    array_push($arr2, &$obj);
     
     
    $obj->setVar('poop');
     
     
    var_dump($arr1);
     
    var_dump($arr2);
     
     class 
    Test {
     
         function 
    Test(){}
     
         function 
    setVar($val)
         {   
    $this->objVar $val;
         }
     
     }
     
     
    ?>
    --ed

  12. #12
    Non-Member coo_t2's Avatar
    Join Date
    Feb 2003
    Location
    Dog Street
    Posts
    1,819
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Guess I could of posted the output too.

    Code:
     
     object(test)(0) {
     }
     array(1) {
       [0]=>
       object(test)(0) {
       }
     }
     array(1) {
       [0]=>
       &object(test)(1) {
     	["objVar"]=>
     	string(4) "poop"
       }
     }

  13. #13
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @coo_t2
    It is standard practice to use 'foo' and 'bar' for all example string constants
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  14. #14
    Non-Member coo_t2's Avatar
    Join Date
    Feb 2003
    Location
    Dog Street
    Posts
    1,819
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by sweatje
    @coo_t2
    It is standard practice to use 'foo' and 'bar' for all example string constants
    Ah, sorry bout that, it's the first thing that came to my mind

    --ed

  15. #15
    SitePoint Member
    Join Date
    Mar 2004
    Location
    USA
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    1 Thread(s)
    Okay,

    I see your point about Stack. Thanks for everyones input. Atleast I think I got input on my classes. Yeah I did.

    Thanks Christian for explaining more about why you think composition should be used instead of direct inheritance.

    Regards,

    php

  16. #16
    SitePoint Addict moonchild's Avatar
    Join Date
    Nov 2003
    Location
    U$A
    Posts
    258
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    what the $@% is vector and stack?????


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •