变量计数过高实施美国国旗在Lua排序

时间:2016-06-15 00:14:32

标签: sorting lua

我应该在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}上执行算术运算}}

我读过/使用过的网站:

0 个答案:

没有答案