编写寻找若干个数字使它们加起来等于某一特定数值的函数
2021-2-23 20:36:39
收藏:0
阅读:125
评论:3
我需要一个函数,它可以找到一定数量的数字,这些数字必须一起加起来等于某一个特定的值。在这个例子中,它等于8。
可以相加的数字是预先定义好的,在一个表格中,以便使事情更容易处理。
目前的方法:使用一个小算法洗牌表格,将前 X 个值相加,如果它们不等于8,就重新开始(包括重新洗牌),直到前 X 个值相加等于8。
我的代码确实可以工作,只有两个问题:它处理时间很长(显然),并且如果我没有添加冷却时间,它可能会导致堆栈溢出错误。
代码可能很糟糕,它不是为现场生产而设计的。我只是一个中级的lua开发者......
function sleep (a) -- 我发现的随机睡眠函数
local sec = tonumber(os.clock() + a);
while (os.clock() < sec) do
end
end
function shuffle(tbl) -- 我发现的随机洗牌函数
for i = #tbl, 2, -1 do
math.randomseed( os.time() )
math.random();math.random();math.random();math.random();
local j = math.random(i)
tbl[i], tbl[j] = tbl[j], tbl[i]
end
return tbl
end
local times = {
0.5,
1.0,
1.5,
2.0,
2.5,
3.0,
3.5,
4.0
}
local timeunits = {} --参考第49行,我不想那样做...
function nnumbersto8(amount)
local sum = 0
local numbs = {}
times = shuffle(times) --重新洗牌集合
for i = 1,amount,1 do --将前 x 个值相加
sum = sum + times[i]
numbs[i] = times[i]
end
if sum ~= 8 then sleep(0.1) nnumbersto8(amount) return end --如果它们不是8,重复这个过程,使用冷却来避免堆栈溢出
--return numbs -- 这个不工作,出了函数没东西返回。
timeunits = numbs
end
nnumbersto8(5) -- 现在手动运行它
print(unpack(timeunits))
难道没有更简单的方法吗? 不管怎样,在此提前感谢,任何帮助都将不胜感激!
点赞
用户572670
这是具有选择元素数量的额外限制的子集和问题。解决方案是使用类似于常规子集和的动态规划,但添加一个额外的变量表示已使用的项目数。
应该按以下方式进行:
失败的停止子句:
DP [ -1 ] [ x ] [n] = false,对于所有 x,n > 0 //超出元素
DP [i] [-1] [n] = false,对于所有 i,n > 0 //超过 X 项
DP [i] [x] [n] = false n <0 //通过总和限制。如果所有元素均为非负数,则这是一种优化。
成功的停止子句:
DP [i] [0] [0] = true,对于所有 i> = 0
递归公式:
DP [i] [x] [n] = DP [i-1] [x] [n] OR DP [i-1] [x-1] [n- item [ i ]] //注意n <item [i]情况。
^ ^
未使用项目已使用项目
2021-02-23 22:14:27
用户585411
下面是一种适用于大量元素的方法,并将每个解决方案以理论上相同的可能性随机选取。
function solution_node (value, count, remainder)
local node = {}
node.value = value
node.count = count
node.remainder = remainder
return node
end
function choose_solutions (node1, node2)
if node1 == nil then
return node2
elseif node2 == nil then
return node1
else
-- 以随机方式选择哪个解决方案。
if node1.count < math.random(node1.count + node2.count) then
node2.count = node1.count + node2.count
return node2
else
node1.count = node1.count + node2.count
return node1
end
end
end
function decode_solution (node)
if node == nil then
return nil
end
answer = {}
while node.value ~= nil do
table.insert(answer, node.value)
-- 这使得解决方案被随机洗牌。
local i = math.random(#answer)
answer[#answer], answer[i] = answer[i], answer[#answer]
node = node.remainder
end
return answer
end
function random_sum(tbl, count, target)
local choices = {}
-- 在 Lua 中,通常数组不是从 0 开始的,但这很方便。
for j = 0,count do
choices[j] = {}
end
-- 确保空集存在。
choices[0][0.0] = solution_node(nil, 1, nil)
for i = 1,#tbl do
for j = count,1,-1 do
for this_sum, node in pairs(choices[j-1]) do
local next_sum = this_sum + tbl[i]
local next_node = solution_node(tbl[i], node.count, node)
-- 尝试将此值添加到一个解决方案中。
if next_sum <= target then
choices[j][next_sum] = choose_solutions(next_node, choices[j][next_sum])
end
end
end
end
return decode_solution(choices[count][target])
end
local times = {
0.2,
0.3,
0.5,
1.0,
1.2,
1.3,
1.5,
2.0,
2.5,
3.0,
3.5,
4.0
}
math.randomseed( os.time() )
local result = random_sum(times, 5, 8.0)
print("answer")
for k, v in pairs(result) do print(v) end
2021-02-24 01:42:47
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

没有解决方案适用于1、2和大于5的值,因此该函数只接受3、4和5。
这里我们进行了
times表的浅复制,然后从副本中获取一个随机索引并开始搜索解决方案,在进行过程中,我们会移除已使用的值。local times = { 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0 } function nNumbersTo8(amount) if amount < 3 or amount > 5 then return {} end local sum = 0 local numbers = {} local set = {table.unpack(times)} for i = 1, amount - 1, 1 do local index = math.random(#set) local value = set[index] if not (8 < (sum + value)) then sum = sum + value table.insert(numbers, value) table.remove(set, index) else break end end local reminder = 8 - sum for _,v in ipairs(set)do if v == reminder then sum = sum + v table.insert(numbers, v) break end end if #numbers == amount then return numbers else return nNumbersTo8(amount) end endfor i=1,100 do print(table.unpack(nNumbersTo8(5))) end示例响应: