我应该在O(N)运行时和常量内存空间中对一个(大)整数数组(正数)进行排序。 American Flag Search算法似乎符合我的需要,所以我尝试使用Lua自己实现它(同时在维基百科页面上使用Phyton代码作为一般准则)。由于某种原因,我的一个交换变量计数太高,导致Lua抛出错误,因为该键没有在表中指定值。我不能确切地指出为什么会这样。
到目前为止,我已经提出了代码(Lua 5.3)
array = {1, 5, 3, 4, 6, 9, 8, 2, 7}
local function max_val(array)
local max = 0
for _,v in pairs(array) do
if max < v then
max = v
end
end
return max
end
local function get_radix_val(x, digit, radix)
return (math.floor(x / (radix^digit)) % radix)
end
local function compute_offsets(array, start, _end, digit, radix)
local counts = {}
local offsets = {}
local sum = 0
for i=1, radix do
counts[i] = 0
end
for i = start, _end do
io.write("COMPUTE OFFSETS: Start: " .. start .. ", _end: " .. _end .. ", digit: " .. digit .. ", radix: " .. radix ..", array[i]: " .. array[i])
val = get_radix_val(array[i], digit, radix)
io.write(", val:" .. val .. "\n")
counts[val] = counts[val]+1
end
for i = 1, radix-1 do
offsets[i] = sum
sum = sum + counts[i]
io.write("COMPUTE OFFSETS: i: " .. i .. ", counts[i]: " .. counts[i] .. ", offsets[i]: " .. offsets[i] .. "\n")
end
return offsets
end
local function swap(array, offsets, start, _end, digit, radix)
local i = start
local cur_block = 0
while cur_block < radix-1 do
io.write("SWAP: cur_block:" .. cur_block)
if i >= start + offsets[cur_block+1] then
cur_block = cur_block+1
io.write("\n")
goto continue
end
radix_val = get_radix_val(array[i], digit, radix)
io.write(", radix_val:" .. radix_val)
if radix_val == cur_block then
i = i+1
io.write("\n")
goto continue
end
swap_to = offsets[radix_val]
io.write(", swap_to:" .. swap_to .. ", CURRENT ARRAY: ")
array[i], array[swap_to] = array[swap_to], array[i]
offsets[radix_val] = offsets[radix_val]+1
for _,v in ipairs(array) do
io.write(v .." ")
end
io.write("\n")
::continue::
end
end
local function sort_helper(array, start, _end, digit, radix)
print("SORT HELPER: Start: " .. start .. ", _end: " .. _end .. ", digit: " .. digit .. ", radix: " .. radix)
offsets = compute_offsets(array, start, _end, digit, radix)
swap(array, offsets, start, _end, digit, radix)
if digit == 0 then
return
end
for i = 1, #offsets-1 do
sort_helper(array, offsets[i], offsets[i-1], digit-1, radix)
end
end
local function sort(array, radix)
for k, v in ipairs(array) do
array[k] = math.abs(v)
end
max_value = max_val(array)
max_digit = math.floor(math.log(max_value, radix))
sort_helper(array, 1, #array, max_digit, radix)
end
sort(array, 10)
输出:
SORT HELPER: Start: 1, _end: 9, digit: 0, radix: 10
COMPUTE OFFSETS: Start: 1, _end: 9, digit: 0, radix: 10, array[i]: 1, val:1
COMPUTE OFFSETS: Start: 1, _end: 9, digit: 0, radix: 10, array[i]: 5, val:5
COMPUTE OFFSETS: Start: 1, _end: 9, digit: 0, radix: 10, array[i]: 3, val:3
COMPUTE OFFSETS: Start: 1, _end: 9, digit: 0, radix: 10, array[i]: 4, val:4
COMPUTE OFFSETS: Start: 1, _end: 9, digit: 0, radix: 10, array[i]: 6, val:6
COMPUTE OFFSETS: Start: 1, _end: 9, digit: 0, radix: 10, array[i]: 9, val:9
COMPUTE OFFSETS: Start: 1, _end: 9, digit: 0, radix: 10, array[i]: 8, val:8
COMPUTE OFFSETS: Start: 1, _end: 9, digit: 0, radix: 10, array[i]: 2, val:2
COMPUTE OFFSETS: Start: 1, _end: 9, digit: 0, radix: 10, array[i]: 7, val:7
COMPUTE OFFSETS: i: 1, counts[i]: 1, offsets[i]: 0
COMPUTE OFFSETS: i: 2, counts[i]: 1, offsets[i]: 1
COMPUTE OFFSETS: i: 3, counts[i]: 1, offsets[i]: 2
COMPUTE OFFSETS: i: 4, counts[i]: 1, offsets[i]: 3
COMPUTE OFFSETS: i: 5, counts[i]: 1, offsets[i]: 4
COMPUTE OFFSETS: i: 6, counts[i]: 1, offsets[i]: 5
COMPUTE OFFSETS: i: 7, counts[i]: 1, offsets[i]: 6
COMPUTE OFFSETS: i: 8, counts[i]: 1, offsets[i]: 7
COMPUTE OFFSETS: i: 9, counts[i]: 1, offsets[i]: 8
SWAP: cur_block:0
SWAP: cur_block:1, radix_val:1
SWAP: cur_block:1
SWAP: cur_block:2, radix_val:5, swap_to:4, CURRENT ARRAY: 1 4 3 5 6 9 8 2 7
SWAP: cur_block:2, radix_val:4, swap_to:3, CURRENT ARRAY: 1 3 4 5 6 9 8 2 7
SWAP: cur_block:2, radix_val:3, swap_to:2, CURRENT ARRAY: 1 3 4 5 6 9 8 2 7
SWAP: cur_block:2, radix_val:3, swap_to:3, CURRENT ARRAY: 1 4 3 5 6 9 8 2 7
SWAP: cur_block:2, radix_val:4, swap_to:4, CURRENT ARRAY: 1 5 3 4 6 9 8 2 7
SWAP: cur_block:2, radix_val:5, swap_to:5, CURRENT ARRAY: 1 6 3 4 5 9 8 2 7
SWAP: cur_block:2, radix_val:6, swap_to:5, CURRENT ARRAY: 1 5 3 4 6 9 8 2 7
SWAP: cur_block:2, radix_val:5, swap_to:6, CURRENT ARRAY: 1 9 3 4 6 5 8 2 7
SWAP: cur_block:2, radix_val:9, swap_to:8, CURRENT ARRAY: 1 2 3 4 6 5 8 9 7
SWAP: cur_block:2, radix_val:2
SWAP: cur_block:2, radix_val:3, swap_to:4, CURRENT ARRAY: 1 2 4 3 6 5 8 9 7
SWAP: cur_block:2, radix_val:4, swap_to:5, CURRENT ARRAY: 1 2 6 3 4 5 8 9 7
SWAP: cur_block:2, radix_val:6, swap_to:6, CURRENT ARRAY: 1 2 5 3 4 6 8 9 7
SWAP: cur_block:2, radix_val:5, swap_to:7, CURRENT ARRAY: 1 2 8 3 4 6 5 9 7
SWAP: cur_block:2, radix_val:8, swap_to:7, CURRENT ARRAY: 1 2 5 3 4 6 8 9 7
SWAP: cur_block:2, radix_val:5, swap_to:8, CURRENT ARRAY: 1 2 9 3 4 6 8 5 7
SWAP: cur_block:2, radix_val:9, swap_to:9, CURRENT ARRAY: 1 2 7 3 4 6 8 5 9
SWAP: cur_block:2, radix_val:7, swap_to:6, CURRENT ARRAY: 1 2 6 3 4 7 8 5 9
SWAP: cur_block:2, radix_val:6, swap_to:7, CURRENT ARRAY: 1 2 8 3 4 7 6 5 9
SWAP: cur_block:2, radix_val:8, swap_to:8, CURRENT ARRAY: 1 2 5 3 4 7 6 8 9
SWAP: cur_block:2, radix_val:5, swap_to:9, CURRENT ARRAY: 1 2 9 3 4 7 6 8 5
SWAP: cur_block:2, radix_val:9, swap_to:10, CURRENT ARRAY: 1 2
SWAP: cur_block:2
lua: sort.lua:14: attempt to perform arithmetic on a nil value (local 'x')
stack traceback:
sort.lua:14: in upvalue 'get_radix_val'
sort.lua:48: in upvalue 'swap'
sort.lua:70: in upvalue 'sort_helper'
sort.lua:85: in local 'sort'
sort.lua:88: in main chunk
[C]: in ?
swap_to
大于10,会被array[i], array[swap_to] = array[swap_to], array[i]
复制,然后在尝试使用get_radix_val()
时会中断,因为array[i]
会尝试在{{1}上执行算术运算}}
我读过/使用过的网站: