《Lua程序设计(第四版)》 第18章练习题

亲自动手写一遍,加深印象

掌握迭代器还是蛮重要的,项目中就使用迭代器做数据管理。

练习18.1 请编写一个迭代器fromto,使得如下循环与数值型for等价,你能否以无状态迭代器实现?

练习18.2 向上一个练习中的迭代器增加一个步进的参数。你能否也用无状态迭代器实现?

for i in fromto(n,m) do
    body
end

18.1 & 18.2一起回答:

--迭代器
local function iter(data,i)
	local pace = data.pace or 1
    i = i + pace
    if data.max < i then return nil end
    return i
end

--迭代器工厂 开始,结尾,步距
function fromto(n,m,p)
    local data = {} --将结尾与步距打包
    data.max = m
    data.pace = p  
	local pace = data.pace or 1
    return iter,data ,n - pace
end

输出结果:

 

练习18.3 请编写一个迭代器uniquewords,该迭代器返回指定文件中没有重复的所有单词(提示:基于示例18.1中allwords,使用一个表来存储已经处理过的所有单词)。

function uniquewords(path)
	io.input(path)
	local line = io.read() 	    --当前行
	local pos = 1 			    --当前行的当前位置
    local wordList = {}         --将已经找到的单词缓存在闭包中
	return function()		    --迭代函数
		while line do 
			local w,e = string.match(line,"(%w+)()",pos)
            if w and wordList[w] == nil then
                wordList[w] = 1
				pos = e
				return w
			elseif w and not wordList[w] == nil then
				pos = e
			else
				line = io.read()
				pos = 1
			end
		end
		return nil
	end
end

输出结果:

 

练习18.4 请编写一个迭代器,该迭代器可以返回指定字符串的所有非空子串

function allsubstr(str)
	local startIndex = 1
	local endIndex = 0
	local length = str and #str or 0
	
	return function()
		endIndex = endIndex + 1
		if endIndex > length then 
			startIndex = startIndex + 1
			endIndex = startIndex
		end
		if startIndex > length then
			return nil
		end
		return string.sub(str,startIndex,endIndex)
	end
end

输出结果:

练习18.5 请编写一个真正的迭代器,该迭代器遍历指定集合的所有子集(该迭代器可以使用同一个表来保存所有结果,只需要在每次迭代时改变表的内容即可,不需要为每个子集创建一个新表)。

--真正的迭代器
function allsubagg(list,func)  --集合aggregation
	local sublist = {}
	table.insert(sublist,{}) --空集也是一个子集
	for k,v in pairs(list) do

		--第一步,拷贝一个结果集 等同于 copyResult  = table.copy(sublist) 
		local copyResult = {} 
		for _,v1 in pairs(sublist) do 
			local subCopyResult = {}
			for _,v2 in pairs(v1) do
				table.insert(subCopyResult,v2)
			end			
			table.insert(copyResult,subCopyResult)
		end
		
		--第二步,在拷贝出来的结果集copyResult中插入元素
		for _,v1 in pairs(copyResult) do 
			table.insert(v1,v)
		end
		
		--第三步,将拷贝出来的结果集合集与原结果集合并 等同于 sublist = sublist + copyResult
		for _,v1 in pairs(copyResult) do 
			table.insert(sublist,v1)
		end
	end
	
	--执行迭代回调
	for	i=1,#sublist do 
		func(sublist[i])
	end
end


--输出表格内容
function printTable(_table)
	print('{'..table.concat(_table,',')..'}')
end


--测试
allsubagg({4,5,6},printTable)

输出结果

本文地址:https://blog.csdn.net/xc1313741/article/details/110904891

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐