打乱和解读字符串 (Lua)
Shuffle and unscramble a string (Lua)
我有一个函数可以随机播放 中的字符串,适用于使用 table 预定义数字重新排序字符。它工作得很好,所以我还需要一个函数来使用数字 table 来解读这个字符串,但我不知道该怎么做,尤其是在尝试并失败了几次之后。
随机播放功能:
randomValues = {}
for i = 1, 60 do
table.insert(randomValues, 1, math.random())
end
function shuffle(str)
math.randomseed(4)
local letters = {}
local idx = 0
for letter in str:gmatch'.[8-1]*' do
idx = idx + 1
table.insert(letters, {letter = letter, rnd = randomValues[idx]})
end
table.sort(letters, function(a, b) return a.rnd < b.rnd end)
for i, v in ipairs(letters) do
letters[i] = v.letter
end
return table.concat(letters)
end
有什么建议吗?
我假设您要做的是:
- 将字符串拆分为 unicode 字符。
- 随机播放这些字符。
- 将字符恢复到原来的位置。
我将 unicode 字符的拆分和实际的随机播放分开了,以使其更容易理解。
1。拆分字符
从字符拆分开始:
-- Splits a string into a table of unicode characters.
local function splitLetters(str)
local letters = {}
for letter in str:gmatch'.[8-1]*' do
table.insert(letters, letter)
end
return letters
end
这主要是从您函数的第一部分复制而来。
2。洗牌 table 个字符
现在我们已经有了可以使用的 table 个不错的字符,是时候洗牌了。可以通过按顺序遍历每个字符并将其与随机选择(但仍未打乱)的项目交换来完成打乱列表。在这样做的同时,我们还保留了所有已交换索引的 table,我在这里称之为 swapTable
。
-- Shuffles in place and returns a table, which can be used to unshuffle.
local function shuffle(items)
local swapTable = {}
for i = 1, #items - 1 do
-- Swap the first item with a random item (including itself).
local j = math.random(i, #items)
items[i], items[j] = items[j], items[i]
-- Keep track of each swap so we can undo it.
table.insert(swapTable, j)
-- Everything up to i is now random.
-- The last iteration can be skipped, as it would always swap with itself.
-- See #items - 1 at the top of the loop.
end
return swapTable
end
3。将字母恢复到原来的位置
使用此 swapTable
,现在可以非常简单地再次进行整个洗牌,但相反。
-- Restores a previous shuffle in place.
local function unshuffle(items, swapTable)
-- Go through the swap table backwards, as we need to do everything in reverse.
for i = #swapTable, 1, -1 do
-- Do the same as before, but using the swap table.
local j = swapTable[i]
items[i], items[j] = items[j], items[i]
end
end
使用所有这些函数的完整示例
使用这几个函数(和table.concat
再次将字母列表构建成字符串)我们可以做任何你想做的事:
-- Make our output reproducible
math.randomseed(42)
-- Split our test string into a table of unicode characters
local letters = splitLetters("Hellö Wörld! Höw are yoü?")
-- Shuffle them in-place, while also getting the swapTable
local swapTable = shuffle(letters)
-- Print out the shuffled string
print(table.concat(letters)) --> " rH?doröWüle Hl lwa eyöö!"
-- Unshuffle them in-place using the swapTable
unshuffle(letters, swapTable)
-- And we're back to the original string
print(table.concat(letters)) --> "Hellö Wörld! Höw are yoü?"
预先创建 swapTable
在您的示例中,您预先生成 swapTable
(它对您的工作方式也略有不同)。您当然可以将那部分拆分出来,让 shuffle
函数的工作方式类似于 unshuffle
目前的实现方式。如果你想让我详细说明,请告诉我。
我有一个函数可以随机播放
随机播放功能:
randomValues = {}
for i = 1, 60 do
table.insert(randomValues, 1, math.random())
end
function shuffle(str)
math.randomseed(4)
local letters = {}
local idx = 0
for letter in str:gmatch'.[8-1]*' do
idx = idx + 1
table.insert(letters, {letter = letter, rnd = randomValues[idx]})
end
table.sort(letters, function(a, b) return a.rnd < b.rnd end)
for i, v in ipairs(letters) do
letters[i] = v.letter
end
return table.concat(letters)
end
有什么建议吗?
我假设您要做的是:
- 将字符串拆分为 unicode 字符。
- 随机播放这些字符。
- 将字符恢复到原来的位置。
我将 unicode 字符的拆分和实际的随机播放分开了,以使其更容易理解。
1。拆分字符
从字符拆分开始:
-- Splits a string into a table of unicode characters.
local function splitLetters(str)
local letters = {}
for letter in str:gmatch'.[8-1]*' do
table.insert(letters, letter)
end
return letters
end
这主要是从您函数的第一部分复制而来。
2。洗牌 table 个字符
现在我们已经有了可以使用的 table 个不错的字符,是时候洗牌了。可以通过按顺序遍历每个字符并将其与随机选择(但仍未打乱)的项目交换来完成打乱列表。在这样做的同时,我们还保留了所有已交换索引的 table,我在这里称之为 swapTable
。
-- Shuffles in place and returns a table, which can be used to unshuffle.
local function shuffle(items)
local swapTable = {}
for i = 1, #items - 1 do
-- Swap the first item with a random item (including itself).
local j = math.random(i, #items)
items[i], items[j] = items[j], items[i]
-- Keep track of each swap so we can undo it.
table.insert(swapTable, j)
-- Everything up to i is now random.
-- The last iteration can be skipped, as it would always swap with itself.
-- See #items - 1 at the top of the loop.
end
return swapTable
end
3。将字母恢复到原来的位置
使用此 swapTable
,现在可以非常简单地再次进行整个洗牌,但相反。
-- Restores a previous shuffle in place.
local function unshuffle(items, swapTable)
-- Go through the swap table backwards, as we need to do everything in reverse.
for i = #swapTable, 1, -1 do
-- Do the same as before, but using the swap table.
local j = swapTable[i]
items[i], items[j] = items[j], items[i]
end
end
使用所有这些函数的完整示例
使用这几个函数(和table.concat
再次将字母列表构建成字符串)我们可以做任何你想做的事:
-- Make our output reproducible
math.randomseed(42)
-- Split our test string into a table of unicode characters
local letters = splitLetters("Hellö Wörld! Höw are yoü?")
-- Shuffle them in-place, while also getting the swapTable
local swapTable = shuffle(letters)
-- Print out the shuffled string
print(table.concat(letters)) --> " rH?doröWüle Hl lwa eyöö!"
-- Unshuffle them in-place using the swapTable
unshuffle(letters, swapTable)
-- And we're back to the original string
print(table.concat(letters)) --> "Hellö Wörld! Höw are yoü?"
预先创建 swapTable
在您的示例中,您预先生成 swapTable
(它对您的工作方式也略有不同)。您当然可以将那部分拆分出来,让 shuffle
函数的工作方式类似于 unshuffle
目前的实现方式。如果你想让我详细说明,请告诉我。