您的位置:首页 > 编程语言 > Lua

第十课 完整的Lua代码示例

2016-12-15 14:47 633 查看
马尔可夫链算法
根据原始文本中n个单词的序列来确定后面的单词,从而生成随机的文本。
程序先读取原始文本,并创建一个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"},
["more we"] = {"try", "do"},
["we try"] = {"the"},
["try the"] = {"more"},
["we do"] = {"\n"},
}
程序将这个table保存在变量statetab中。若要 向此table中的某个前缀列表插入一个新 单词,可以使用以下函数:
function insert (index, value)

local list = statetab[index]

if list == nil then

statetab[index] = {value} --没有就新加

else

list[#list + 1] = value --有就在列表末尾增加一个

end
end
辅助函数:
function allwords ()

local line = io.read()

local pos = 1

return function () --迭代器函数

while line do

local s, e = string.find(line, "%w+", pos)

if s then

pos = e + 1

return string.sub(line, s ,e)

else

line = io.read()

pos = 1

end

end

return nil

end
end

主程序:
local N = 2
local MAXGEN = 10000
local NOWORD = "\n"

--构建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)

--生成文本
w1 = NOWORD; w2 = NOWORD
for i = 1, MAXGEN do

local list = statetab[prefix(w1, w2)]

--从列表中选择一个 随机项

local r = math.random(#list)

local nextword = list[r]

if nextword == NOWORD then return end

io.write(nextword, " ")

w1 = w2; w2 = nextword
end

输入:
i am a pretty boy and i have a beautiful pig
i love my pig forever and i hope her happiness as long as her life
if you also have a cherished person i hope you can stay with her as long as possible
可能的输出:
i am a pretty boy and i hope her happiness as long as possible
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Lua 语言 函数 算法