Quick mastery of LUA 5.3--data structures

Source: Internet
Author: User
Tags data structures garbage collection joins lua reserved
Q: How to implement a one-dimensional array using "table".

A:

--Use the construction method.
squares = {1, 4, 9, +, +, +, +, Bayi}

--Use the "for" loop + continuous index.
a = {}    --new array
for I=1,
  a[i] = 0
End--

of course, consecutive indexes must be positive.
a = {}
for i=-5, 5 does
  a[i] = 0
End
Q: How to use "table" to implement multidimensional arrays.

A:

--Here is an example of a two-dimensional array, with the same multidimensional array principle.
--Use nested "table" method.
mt = {}          --Create the Matrix
for I=1, N does
  mt[i] = {}     --Create a new row
  for j = 1, M do
  MT[I][J] = 0
  End
End
Q: How to use "table" to implement the linked list.

A:

List = Nil
--insert.
List = {next = list, value = v}
--traversal.
local L = list while
l do
  print (l.value)
  L = L.next
End

In Lua you rarely need to use linked lists because there is a better way to organize your data than using a linked list. For example, to implement a stack, you can use an array plus a variable that stores the top index of the stack without using a linked list. Q: How to implement queues and stacks using "table".

A: The following example realizes the queue, and implements the stack,

-In order to avoid polluting the global space, the functions and data are stored in a table named list.
list = {}
function list.new ()
  return {first = 0, last =-1}
end

function List.pushleft (List, value)
  local first = list.first-1
  List.first = First
  List[first] = value
end

function list.pushright (LIS T, value)
  Local last = list.last + 1
  list.last = Last
  list[last] = value
End

function list.pople FT (list)
  local first = List.first
  if first > List.last then error ("List is empty") End
  Local value = Li St[first]
  List[first] = nil        --to allow garbage collection
  List.first = first + 1
  return value
E  nd

function list.popright (list)
  Local last = List.last
  if List.first > last then error ("List is empty") End
  Local value = List[last]
  list[last] = nil         --to allow garbage collection
  List.last = LAST-1
  return Value
End

When used as a queue, you can use Pushright () to Enqueue, use Popleft () out of the team (or Pushleft () Enqueue, Popright () out of the team.
When used as a stack, you can use Pushright () into the stack, using Popright () out of the stack (or pushleft () queue, popright () out of the queue. Q: How to implement a collection using "table".

A: The name of the element in the collection is indexed as "table", and the value of the element in "table" is assigned to True,

--[["While", "End", "function", "local" are all Lua's keywords,
     so you can't directly write "while = true" style, will error. ]]
reserved = {
  ["while"] = True,     ["end"] = True,
  ["function"] = True,  ["local"] = True,
  my_ Identifiers = True, 
}

--You can quickly determine whether an element is in the collection.
if RESERVED[W] then    --in the collection.
   ...
Else    --not in the collection.
   ...
End
Q: How to use "table" to implement string caching.

A: The following example reads the data from a line in a file, and then combines the data that is read into a whole string,

Local t = {}
for lines in Io.lines ("file") does    --reads data from a row of files.
    Table.insert (t, line)    -reads each row of data as a member of the table.
End
--[["Table.concat ()" Does not add a delimiter to the last string in "table",
     so insert an empty string at the end of "T" so that
     "Table.concat ()" Inserts a delimiter between this empty string and the original last string. ]]
Table.insert (t, "")
--[["Table.concat ()" joins all string members in "T"
     and adds the specified delimiter between each string. ]]
s = table.concat (t, "\ n")
Additional:

1. "Table" is not a data structure in Lua, but the only one in Lua. Many other languages provide data structures, such as array,list,queue,set, that can be implemented efficiently in LUA using "table".
2, the creation of the collection can also use the way of auxiliary functions to implement,

function Set (list)
  local set = {}
  for _, L-ipairs (list) do set[l] = True End
  return Set
end
R eserved = set{"while", "End", "function", "Local",}

3. Implementing a string cache has a way of not using "table",

--Warning:bad Code ahead!!
Local buff = "" For line in
io.lines ("file") do
    buff = buff. Line.. "\ n"
end

This implementation is acceptable for small files, but performance is very low for large files. Testing on my machine, using this method to read a 1M size, the 20000-line file takes 5.1 seconds, and the program in the "Q & A" example reads the same file for only 0.030 seconds.
Why there is such a big gap. The culprit is the string connector ...
LUA uses a real garbage collection algorithm, and when he discovers that the program uses too much memory, he iterates through all the data structures used by the program and frees up data structures (garbage) that are no longer being used. In general, this algorithm has good performance (LUA's efficiency is not accidental), but the cycle of the above code makes the algorithm extremely inefficient.
To understand the nature of the phenomenon, assume that our for loop has been running for a while, the buff has already stored a 50KB string, and each row has a size of 20bytes. When the program executes again to the buff: Line: " \ n ", he created a new string of size 50,020bytes (all the strings in Lua are constants and cannot change any of them, so.) is to create a new string) and copy the 50KB string from the buff to the new string. In other words, 50KB of memory is moved for each row, and more and more. When it reads to 100 lines (just 2KB), Lua has moved 5MB of memory.
These memory copies are only part of the reason, making the situation worse is the following assignment statement,
Buff = buff. Line.. "\ n"
The old string becomes junk data, and after two rounds there will be two old strings containing more than 100KB of junk data. This time Lua will make the right decision, carry out his garbage collection and release this 100KB of memory. The problem is that every two cycles of LUA will have to be garbage collected, read to 20000 rows of the time 10,000 garbage collection, the recovery of memory up to 1GB, the light of the recovered memory is already the original file size of 1000 times times.
4, if must be used. Way to implement the string cache, we will use a slightly more efficient algorithm. The original algorithm solves the problem by connecting the strings of each row to the old string, and the new algorithm avoids this. It connects two short strings into a slightly longer string, and then joins two slightly longer strings to become longer strings. The core of the algorithm is to use a stack at the bottom of the stack to hold the long string that has been generated, and the short string to stack from the top of the stack. The state of the stack is similar to the classic Nottingham question: The string below the stack is definitely longer than the above. As long as a string is longer than the string below it, the two strings are combined into a new, longer string. The newly generated string continues to be compared with the adjacent string, if longer than the following string will continue to merge, looping until no strings can be merged or reached the bottom of the stack.

function Newstack ()
  return {""}   --Starts with an empty string
end

function addstring (stack, s)
  tab Le.insert (Stack, s)    --Push's ' into the stack for
  i = #stack-1, 1,-1 do
    if String.len (Stack[i]) > S Tring.len (stack[i+1]) then
      break
    end
    Stack[i] = Stack[i]: table.remove (stack)
  end
End

To get the final string, we just need to merge all the strings from the top of the stack to the bottom of the stack,

Local s = newstack ()
for line in Io.lines ("file") does
    addstring (s, line)
end
s = Table.concat (s)

Using this implementation to read the same file as "Q & A" takes 0.055 seconds.
5, if read the file, the quickest way is still io.read (*all),

Io.input ("file")
t = io.read ("*all")

Using Io.read (*all) to read the same files as "Q & A" takes only 0.007 seconds.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.