lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> Being able to shrink an array is vital to using it as a stack. If you
> don't need to push nils, you can use "t[#t] = val" for a push
> operation and "t[#t] = nil" for a pop operation. If you have auto-grow
> functionality, then "t[#t] = val" still works, but you'd need
> something like "t.resize(#t-1)" for pop.

Right, and that's in the code but you need to use __call instead of setlength.
BTW, you don't need arrays to have stacks, but arrays make for a slightly
easier implementation. If we allow non-numeric keys in the array,

  __newindex = function (t, k, v)
    if type(k) == "number" and k == floor(k) and k > t.n then
      t.n = k
    end
    return rawset(t, k, v)
  end

as in Roberto's code, we can store the top of the stack and have stacks with
amortized O(1) push/pop operations:

local array = require "array"

function stack.new ()
  local s = array()
  s.top = 0
  return s
end

function stack.push (s, e)
  if s.top == s.n then -- full?
    s.n = 2 * s.top -- grow
  end
  s.top = s.top + 1
  s[s.top] = e
end

function stack.pop (s)
  if s.top == 0 then return nil end -- empty?
  local e = s[s.top]
  s.top = s.top - 1
  if s.top < s.n / 4 then -- shrink?
    s(math.floor(s.n / 2)) -- or s:setlength(s.n / 2)
  end
  return e
end

Note the shrinking case when the stack is quarter full in stack.pop: it can
either use __call or setlength to shrink the array.

Cheers,
Luis

-- 
Computers are useless. They can only give you answers.
                -- Pablo Picasso

-- 
Luis Carvalho (Kozure)
lua -e 'print((("lexcarvalho@NO.gmail.SPAM.com"):gsub("(%u+%.)","")))'