Lua程序设计第四版第二部分编程实操自做练习题答案,带⭐为重点。
9.1
请编写一个函数integral,该函数以一个函数f为参数并返回其积分的近似值
使用右矩阵法近似积分值- function integral(f)
- return function(a, b)
- local sum = 0
- for i = 1, 10000, 1 do
- sum = sum + f(a + (b - a) * i / 10000)
- end
- return sum * (b - a) / 10000
- end
- end
- function x3(x)
- return 2 * x + 3 * x ^ 3
- end
- jf = integral(x3)
- print(jf(0, 10)) -- 7601.510075 近似 7600
复制代码 9.2
如下代码段将输出什么结果
- function F(x)
- return {
- set = function(y)
- x = y
- end,
- get = function()
- return x
- end
- }
- end
- o1 = F(10)
- o2 = F(20)
- print(o1.get(), o2.get())
- o2.set(100)
- o1.set(300)
- print(o1.get(), o2.get())
- -- 10 20
- -- 300 100
复制代码 9.3 ⭐
编写练习5.4的柯里化版本
柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。- function newpoly(t)
- return function(x)
- local sum = 0
- for i, v in ipairs(t) do
- sum = sum + v * x ^ (i - 1)
- end
- return sum
- end
- end
- t = newpoly({3, 0, 1})
- print(t(0))
- print(t(5))
- print(t(10))
复制代码 9.4
使用几何区域系统的例子,绘制一个北半球所能看到的峨眉月
编写一个被其他函数B包含的函数A时,被包含的函数A可以访问包含其的函数B的所有局部变量,这种特性被称为词法定界- -- 利用高阶函数和词法定界,定义一个指定圆心和半径创建圆盘的工厂 --
- function disk(cx, cy, r)
- return function(x, y)
- return (x - cx) ^ 2 + (y - cy) ^ 2 <= r ^ 2
- end
- end
- -- 创建一个指定边界的轴对称图形
- function rect(left, right, top, bottom)
- return function(x, y)
- return left <= x and x <= right and bottom <= y and y <= top
- end
- end
- -- 创建任何区域的补集
- function complement(r)
- return function(x, y)
- return not r(x, y)
- end
- end
- -- 创建任何区域的并集
- function union(r1, r2)
- return function(x, y)
- return r1(x, y) or r2(x, y)
- end
- end
- -- 交集
- function intersection(r1, r2)
- return function(x, y)
- return r1(x, y) and r2(x, y)
- end
- end
- -- 差集
- function difference(r1, r2)
- return function(x, y)
- return r1(x, y) and not r2(x, y)
- end
- end
- -- 按指定增量平移区域
- function translate(r, dx, dy)
- return function(x, y)
- return r(x - dx, y - dy)
- end
- end
- function plot(r, M, N, file)
- f = io.open(file, "w")
- f:write("P1\n", M, " ", N, "\n")
- for i = 1, N, 1 do
- local y = (N - i * 2) / N
- for j = 1, M do
- local x = (j * 2 - M) / M
- f:write(r(x, y) and "1" or "0")
- end
- f:write("\n")
- end
- f:close()
- end
- circle = disk(0, 0, 0.5)
- circle2 = translate(circle, -0.3, 0.2)
- shape = difference(circle, circle2)
- plot(shape, 512, 512, "test.pbm")
复制代码 13.4
该函数用于计算指定整数的汉明权重(数二进制表示的1的个数)
- -- 创建一个指定边界的轴对称图形
- function rect(left, right, top, bottom)
- return function(x, y)
- return left <= x and x <= right and bottom <= y and y <= top
- end
- end
- -- 创建任何区域的并集
- function union(r1, r2)
- return function(x, y)
- return r1(x, y) or r2(x, y)
- end
- end
- -- 图形根据坐标轴原点顺时针旋转d弧度
- function rotate(r, d)
- return function(x, y)
- return r(-math.cos(d) * x + y * math.sin(d), -math.sin(d) * x - math.cos(d) * y)
- end
- end
- function plot(r, M, N, file)
- f = io.open(file, "w")
- f:write("P1\n", M, " ", N, "\n")
- for i = 1, N, 1 do
- local y = (N - i * 2) / N
- for j = 1, M do
- local x = (j * 2 - M) / M
- f:write(r(x, y) and "1" or "0")
- end
- f:write("\n")
- end
- f:close()
- end
- shape1 = rect(-0.5, 0.5, 0.5, -0.5)
- shape2 = rect(-0.25, 0.25, 0.75, -0.25)
- shape1 = rotate(shape, math.pi * 0.1) -- s1所处的坐标系平面被旋转了,s2的并没有
- shape = union(shape1, shape2)
- plot(shape, 512, 512, "test.pbm")
复制代码 13.5
该函数用于判断注定整数的二进制表示是否为回文数
- function split(s, sep)
- t = {}
- -- tmpindex = 0
- -- index = 1
- -- index = string.find(s, sep, index, true)
- -- while index do
- -- table.insert(t, string.sub(s, tmpindex + 1, index))
- -- tmpindex = index
- -- index = string.find(s, sep, index + 1, true)
- -- end
- -- if index ~= #s then
- -- table.insert(t, string.sub(s, tmpindex + 1, #s))
- -- end
- for w in string.gmatch(s, "[^" .. sep .. "]+") do
- t[#t + 1] = w
- end
- return t
- end
- t = split("a whole new world", " ")
- -- t = split("", " ")
- for k, v in pairs(t) do
- print(k, v)
- end
复制代码 13.6 ⭐
请在Lua语言实现一个比特数组
- newBiteArrary(n) 创建一个具有n个比特的数组
- setBit(a, n, v) 将布尔值v赋值给数组a的第n位
- testBit(a, n) 将第n位的值作为布尔值返回
- [^%d%u] 是 (数字∪大写字母)的补集 = 排除数字和大写字母
- > string.find("123ABCA","[^%d%u]")
- nil
- > string.find("123ABCa","[^%d%u]")
- 7 7
- [%D%U] 是 数字的补集∪大写字母的补集 = 全集
- > string.find("123ABC","[%D%U]")
- 1 1
- 使用第一种是正确的
复制代码 13.7 ⭐
假设有一个以一系列记录组成的二进制文件,其中的每一个记录的格式为- function transliterate(s, t)
- return string.gsub(s, ".", function(w)
- if t[w] == false then
- return ""
- else
- return t[w]
- end
- end)
- end
- s = "apple"
- s = transliterate(s, {
- a = "b",
- p = false,
- l = "i",
- e = "g"
- })
- print(s)
复制代码 请编写一个程序,该程序读取这个文件,然后输出value字段的总和
[code]function saveRecords(t) local f = io.open("records.txt", "w") for _, v in ipairs(t) do f:write(string.pack("j", v.x)) f:write(string.pack("z", v.code)) f:write(string.pack("n", v.value)) end f:close()endfunction readCalcuteValue() local f = io.open("records.txt", "rb") local s = f:read('a') f:close() local i = 1 local total = 0 while i |