天天看點

棧Stack

1 Stack = Stack or {}
  2 
  3 function Stack.new()
  4     local inst = {}
  5     inst._cname = "lang.Stack"
  6     
  7     local arr = {}
  8     local len = 0
  9     
 10     function inst:push(v)
 11         len = len + 1
 12         arr[len] = v
 13     end
 14     
 15     function inst:pop()
 16         assert(len >= 1, "Stack: pop: out of range")
 17         local v = arr[len]
 18         arr[len] = nil
 19         len = len - 1
 20         return v
 21     end
 22     
 23     function inst:peek()
 24         if len >= 1 then
 25             return arr[len]
 26         end
 27         return nil
 28     end
 29     
 30     function inst:count()
 31         return len
 32     end
 33     
 34     function inst:contains(v)
 35         for i=1,len do
 36             if arr[i] == v then
 37                 return true
 38             end
 39         end
 40         return false
 41     end
 42     
 43     function inst:clear()
 44         for i=1,len do
 45             arr[i] = nil
 46         end
 47         len = 0
 48     end
 49     
 50     function inst:copyTo(dst)
 51         assert("table" == type(dst), "copyTo: dst not table or Stack")
 52         if "lang.Stack" == dst._cname then
 53             for i=1,len do
 54                 dst:push(arr[i])
 55             end
 56         else
 57             for i=1,len do
 58                 table.insert(dst, arr[i])
 59             end
 60         end
 61     end
 62     
 63     function inst:__tostring()
 64         if len <= 0 then return "" end
 65         local strTb = {}
 66         for i=1,len do
 67             local item = arr[i]
 68             table.insert(strTb, (nil == item) and "nil" or tostring(item))
 69         end
 70         return table.concat(strTb, ",")
 71     end
 72 
 73     function inst:__len()
 74         return len
 75     end
 76     
 77     function inst:__index(k)
 78         error("Stack: invalid member: " .. k)
 79     end
 80     
 81     function inst:__newindex(k, v)
 82         error("Stack: add member error: " .. k)
 83     end
 84     
 85     function inst:__pairs()
 86         local iterator = function(src, index)
 87             if nil == index then 
 88                 index = len 
 89             else
 90                 index = index - 1
 91             end
 92             if index >= 1 then
 93                 return index, arr[index]
 94             end
 95             return nil, nil
 96         end
 97         return iterator
 98     end
 99     
100     setmetatable(inst, inst)
101     return inst
102 end
103 
104 Stack.__call = function()
105     return Stack.new()
106 end
107 
108 setmetatable(Stack, Stack)      

測試代碼:

1 function Test1()
 2     local stack = Stack()
 3     stack:push("one")
 4     assert(1 == stack:count(), "push error")
 5     assert("one" == stack:peek(), "peek error")
 6     assert("one" == stack:pop(), "pop error")
 7     assert(0 == stack:count(), "pop error")
 8     
 9     assert(nil == stack:peek(), "peek error")
10     
11     for i=1,100 do
12         stack:push(i)
13     end
14     assert(100 == stack:count(), "push error")
15     stack:clear()
16     assert(0 == stack:count(), "push error")
17     
18     stack:push("a")
19     stack:push("b")
20     
21     local s2 = Stack()
22     stack:copyTo(s2)
23     assert(2 == s2:count(), "copyTo error")
24     
25     for k,v in s2:__pairs() do
26         print("k: " .. k .. ": " .. v)
27     end
28     
29     assert("b" == s2:peek(), "peek error")
30     assert("b" == s2:pop(), "pop error")
31     
32     assert("a" == s2:peek(), "peek error")
33     assert("a" == s2:pop(), "pop error")
34     
35     assert(0 == s2:count(), "copyTo error")
36 end
37 
38 
39 Test1()      

繼續閱讀