zoukankan      html  css  js  c++  java
  • 程序functionLua基础 小结(两个Lua程序示例)

    在改章节中,我们主要介绍程序function的内容,自我感到有个不错的建议和大家分享下

        本篇文章作为Lua基础部分的一个小结,演示两个小程序,来表现Lua的不同特性。第一个例子说明Lua如何作为一门数据描述性语言应用。第2个例子,是一个马尔可夫链算法的实现。

        ps:个人认为书中的这一章有点稀里糊涂,感到两个例子也没有起到什么总结作用,反而感到讲得有点云里雾里的。

        

        

    1. 数据描述

        在Lua的网站上保留了一个数据库,存储了世界上应用Lua的项目的一些示例代码。我们用一个结构体来表示数据库中的每个条目,如下所示:

        

    entry{
        title = "Tecgraf",
        org = "Computer Graphics Technology Group, PUC-Rio",
        url = "http://www.tecgraf.puc-rio.br/",
        contact = "Waldemar Celes",
        description = [[
            Tecgraf is the result of a partnership between PUC-Rio,
            the Pontifical Catholic University of Rio de Janeiro,
            and <a HREF="http://www.petrobras.com.br/">PETROBRAS</a>,
            the Brazilian Oil Company.
            Tecgraf is Lua's birthplace,
            and the language has been used there since 1993.
            Currently, more than thirty programmers in Tecgraf use
            Lua regularly; they have written more than two hundred
            thousand lines of code, distributed among dozens of
            final products.]]
    }

        含有一系列这样条目的一个数据文件,居然也是一个Lua程序,它以table为参数去对函数entry 进行一系列调用。

        

        我们要写一个程序将这些数据以HTML格式展示出来,这些数据就变成网页 http://www.lua.org/uses.html。 因为有很多项目,终究的页面先列出所有项目的主题,再展示每个项目的细节。如下所示,是程序的一个典型输出:

        

    <html>
    <head><title>Projects using Lua</title></head>
    <body bgcolor="#FFFFFF">
    Here are brief descriptions of some projects around the
    world that use <a href="home.html">Lua</a>.
    <br>
    <ul>
    <li><a href="#1">Tecgraf</a>
    <li> <other entries>
    </ul>
    <h3>
    <a name="1" href="http://www.tecgraf.puc-rio.br/">Tecgraf</a>
    <br>
    <small><em>Computer Graphics Technology Group,
        PUC-Rio</em></small>
    </h3>
        Tecgraf is the result of a partnership between
        ...
        distributed among dozens of final products.<p>
    Contact: Waldemar Celes
    <a name="2"></a><hr>
    <other entries>
    </body></html>

        为了读取数据,程序简略定义了entry ,然后用dofile 运行该数据文件。注意,我们必须遍历所有的条目两遍,第一次是为了获取主题列表,第二次来获取项目描述信息。一种方法是将所有的条目手收集到一个array中。但是,还有另一个比拟吸引人的方法:运行这个数据文件两次,每次应用不同的entry 定义。下面我们应用第二种方法。

        

        首先,我们定义一个格式化写入的函数:

        

    function fwrite (fmt, ...)
        return io.write(string.format(fmt, ...))
    end

        函数writeheader 简略的写入page header,如下:

        

    function writeheader()
        io.write([[
            <html>
            <head><title>Projects using Lua</title></head>
            <body bgcolor="#FFFFFF">
            Here are brief descriptions of some projects around the
            world that use <a href="home.html">Lua</a>.
            <br>
        ]])
    end

        entry 的第一个定义,将每个项目主题写入到list中为一个条目,参数o  是描述项目的table:

        

    function entry1 (o)
        count = count + 1
        local title = o.title or '(no title)'
        fwrite('<li><a href="#%d">%s</a>\n', count, title)
    end

        如果o.titlenil (也就是说这个域没有被提供),函数应用一个固定的"(no title)"。

        

        entry 的第二个定义如下,写入一个项目的所有有效数据。有一点复杂,因为所有的选项都是可选的。(HTML中应用双引号,为了防止跟HTML冲突,我们在程序中应用单引号)。

        

    function entry2 (o)
        count = count + 1
        fwrite('<hr>\n<h3>\n')
        local href = o.url and string.format(' href="%s"', o.url) or ''
        local title = o.title or o.org or 'org'
        fwrite('<a name="%d"%s>%s</a>\n', count, href, title)
        if o.title and o.org then
            fwrite('<br>\n<small><em>%s</em></small>', o.org)
        end
        fwrite('\n</h3>\n')
        if o.description then
            fwrite('%s<p>\n',
                    string.gsub(o.description, '\n\n+', '<p>\n'))
        end
        if o.email then
            fwrite('Contact: <a href="mailto:%s">%s</a>\n',
                    o.email, o.contact or o.email)
        elseif o.contact then
            fwrite('Contact: %s\n', o.contact)
        end
    end

        最后一个函数writetail ,写page tail。

        

    function writetail ()
        fwrite('</body></html>\n')
    end

        主程序如下所示。程序打开页面,加载数据文件,用entry 的第一个定义(entry1)来创立主题列表,然后重置计数器,再用entry 的第二个定义(entry2)来运行数据文件,最后关闭页面。

        

    local inputfile = 'db.lua'
    writeheader()
    count = 0
    f = loadfile(inputfile) -- loads data file
    entry = entry1 -- defines 'entry'
    fwrite('<ul>\n')
    f() -- runs data file
    fwrite('</ul>\n')
    count = 0
    entry = entry2 -- redefines 'entry'
    f() -- runs data file again
    writetail()

        

        汇总了一下下面的程序代码如下:

    function fwrite (fmt, ...)                                                                                                                                                                                                                                                    
        return io.write(string.format(fmt, ...))
    end
    
    function writeheader()
        io.write([[
        <html>
        <head><title>Projects using lua</title></head>
        <body bgcolor="#FFFFFF">
        Here are brief description of some projects around the world
        that use <a href="home.html">Lua</a>.
        <br>
        ]])
    end
    
    function entry1 (o) 
        count = count + 1 
        local title = o.title or '(no title)'
        fwrite('<li><a href="#%d">%s</a>\n', count, title)
    end
    
    function entry2 (o) 
        count = count + 1 
        fwrite('<hr>\n<h3>\n')
        local href = o.url and string.format(' href="%s"', o.url)
        local title = o.title or o.org or 'org'
        fwrite('<a name="%d"%s>%s</a>\n', count, href, title)
        if o.title and o.org then
            fwrite('<br>\n<small><em>%s</em></small>', o.org)
        end 
        fwrite('\n</h3>\n')
        if o.description then
            fwrite('%s<p>\n',
                    string.gsub(o.description, '\n\n+', '<p>\n'))
        end 
        if o.email then
            fwrite('Contact: <a href="mailto:%s">%s</a>\n',
                    o.email, o.contact or o.email)
        elseif o.contact then
            fwrite('Contact: %s\n', o.contact)
        end 
    end
    
    function writetail ()
        fwrite('</body></html>\n')
    end
    
    local inputfile = 'db.lua'
    writeheader()
    count = 0
    f = loadfile(inputfile) -- loads data file
    entry = entry1 -- defines 'entry'
    fwrite('<ul>\n')
    f() -- runs data file
    fwrite('</ul>\n')
    count = 0
    entry = entry2 -- redefines 'entry'
    f() -- runs data file again
    writetail()
        每日一道理
    聪明人学习,像搏击长空的雄鹰,仰视一望无际的大地;愚笨的人学习,漫无目的,犹如乱飞乱撞的无头飞蛾;刻苦的人学习,像弯弯的河流,虽有曲折,但终会流入大海;懒惰的人学习,像水中的木头,阻力越大倒退得越快。

        db.lua文件的内容如下:

    entry{                                                                                                                                                                                                                                                                        
          title = "Tecgraf",
          org = "Computer Graphics Technology Group, PUC-Rio",
          url = "http://www.tecgraf.puc-rio.br/",
          contact = "Waldemar Celes",
          description = [[
            TeCGraf is the result of a partnership between PUC-Rio,
            the Pontifical Catholic University of Rio de Janeiro,
            and <A HREF="http://www.petrobras.com.br/">PETROBRAS</A>,
            the Brazilian Oil Company.
            TeCGraf is Lua's birthplace,
            and the language has been used there since 1993.
            Currently, more than thirty programmers in TeCGraf use
            Lua regularly; they have written more than two hundred
            thousand lines of code, distributed among dozens of
            final products.]]
          }   
    entry{
          title = "Tecgraf_02",
          org = "Computer Graphics Technology Group, PUC-Rio, the 2nd entry",
          url = "http://www.tecgraf.puc-rio.br/, the 2nd entry",
          contact = "Waldemar Celes 02",
          description = [[
            This is the 2nd entry,
            TeCGraf is the result of a partnership between PUC-Rio,
            the Pontifical Catholic University of Rio de Janeiro,
            and <A HREF="http://www.petrobras.com.br/">PETROBRAS</A>,
            the Brazilian Oil Company.
            TeCGraf is Lua's birthplace,
            and the language has been used there since 1993.
            Currently, more than thirty programmers in TeCGraf use
            Lua regularly; they have written more than two hundred
            thousand lines of code, distributed among dozens of
            final products.]]
          }

        运行结果如下:

        程序和function

        

        

    2. 马尔可夫链算法

        第2个例子是马尔可夫链算法的实现.这个程序基于文本中的前n个词来生成随机的文本,这里我们假设n为2。

        

        程序的第一部分,读取基本文本,并创立一个table,每两个单词为一个前缀,将基本文本中在该前缀之后的单词(可能有多个)存入table中。创立完该table后,程序用这个table去随机生成文本,每个前缀后的单词出现的概率跟在基本文本中大致雷同。这样,我们就得到一个相当随机的文本。

        

        我们会把两个单词用一个空格“ ”链接起来,编码为前缀:

        

    function prefix (w1, w2)
        return w1 .. " " .. w2
    end

        我们应用字符串 NOWORD("\n")来初始化前缀单词,并且标记文本的开头。例如:

        

    the more we try the more we do

        生成的table将会是:

        

    { ["\n \n"] = {"the"},
      ["\n the"] = {"more"},
      ["the more"] = {"we", "we"}, -- 有两处"the more we" 
      ["more we"] = {"try", "do"}, -- 两处"more we try", "more we do"
      ["we try"] = {"the"},
      ["try the"] = {"more"},
      ["we do"] = {"\n"},
    }

        程序将它的table保存到变量statetab中。我们用下面的函数在这个table的前缀list中插入一个新的单词

        

    function insert (index, value)
        local list = statetab[index]
        if list == nil then
            statetab[index] = {value}
        else
            list[#list + 1] = value
        end
    end

        它首先检查这个前缀是否有list了;如果么有,那么用这个新值创立一个新的list;否则,就将这个新值插入到已存在的list的末端。

        

        要创立statetab这个table,我们保存两个变量,w1 和 w2,保存最后读取的两个单词。每读取一个新的单词,我们就将它添加到与w1-w2关联的list中,然后update一下w1和w2。

        

        创立完这个table后,程序开始用MAXGEN个单词来生成文本。首先,它从新初始化w1和w2。然后,对每个前缀,它从合法的下一个单词的list中随机选取一个,打印这个单词,然后update下w1和w2.   下面是完整版的程序。

        

    -- Auxiliary definitions for the Markov program
    
    function allwords ()
        local line = io.read() -- current line
        local pos = 1 -- current position in the line
        return function () -- iterator function
            while line do -- repeat while there are lines
                local s, e = string.find(line, "%w+", pos)
                if s then -- found a word?
                    pos = e + 1 -- update next position
                    return string.sub(line, s, e) -- return the word
                else
                    line = io.read() -- word not found; try next line
                    pos = 1 -- restart from first position
                end
            end
            return nil -- no more lines: end of traversal
        end
    end
    
    function prefix (w1, w2)
        return w1 .. " " .. w2
    end
    
    local statetab = {}
    
    function insert (index, value)
        local list = statetab[index]
        if list == nil then
            statetab[index] = {value}
        else
            list[#list + 1] = value
        end
    end
    
    
    -- The Markov program
    
    local N = 2
    local MAXGEN = 10000
    local NOWORD = "\n"
    
    -- build table
    local w1, w2 = NOWORD, NOWORD
    for w in allwords() do
        insert(prefix(w1, w2), w)
        w1 = w2; w2 = w;
    end
    insert(prefix(w1, w2), NOWORD)
    
    -- generate text
    w1 = NOWORD; w2 = NOWORD -- reinitialize
    for i=1, MAXGEN do
        local list = statetab[prefix(w1, w2)]
        -- choose a random item from list
        local r = math.random(#list)
        local nextword = list[r]
        if nextword == NOWORD then return end
        io.write(nextword, " ")
        w1 = w2; w2 = nextword
    end

        运行结果如下:

        程序和function

        

        水平无限,如果有朋友发明错误,欢送留言交流

        

    文章结束给大家分享下程序员的一些笑话语录: 祝大家在以后的日子里. 男生象Oracle般健壮; 女生象win7般漂亮; 桃花运象IE中毒般频繁; 钱包如Gmail容量般壮大, 升职速度赶上微软打补丁 , 追女朋友像木马一样猖獗, 生活像重装电脑后一样幸福, 写程序敲代码和聊天一样有**。

    --------------------------------- 原创文章 By
    程序和function
    ---------------------------------

  • 相关阅读:
    企业如何搭建数据分析平台
    如何查看Android设备上的分区信息
    从传统企业谈大数据的战略意义
    金融行业的BI应用分析
    Android 5.x 权限问题解决方法
    unity使用ugui自制调色面板
    手机模式及分区
    高通8x12平台开机画面制作工具
    Unity插件
    Android开发小问题集
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3102237.html
Copyright © 2011-2022 走看看