【问题标题】:Lua function fails when input is a multiple of ten当输入是十的倍数时,Lua 函数失败
【发布时间】:2017-01-23 07:36:43
【问题描述】:

我有一个 Lua 函数可以将两位整数转换为书面文字,例如“12”变成“十二”。我以为我已经完成了所有工作,除非我输入的数字是十的直接倍数(10、20、30 等),但代码会失败。

我得到的具体错误是

./.lua/num2word:4: attempt to perform arithmetic on local 'number' (a nil value)
stack traceback:
    ./.lua/num2word:4: in function 'num2wordint'
    ./.lua/num2word:117: in main chunk
    [C]: in ?

但我在任何其他数字上都得到了正确的输出。

我尝试重新定义 number 变量的范围,但它要么在所有情况下都破坏了代码,要么对问题情况没有帮助。

我已经看了几个小时的代码和一堆 lua 支持文档,这超出了我的能力。

#! /usr/local/bin/lua

function num2wordint(number)
    local number = number + 0
    local outstring=""
    if number / 10 >= 9 then
        local remainder = number % 10
        if remainder == 0 then
            outstring= outstring.."Ninety"
        else
            outstring= outstring.."Ninety-"
            return outstring, remainder
        end
    elseif number / 10 >= 8 then
        local remainder = number % 10
        if remainder == 0 then
            outstring= outstring.."Eighty"
        else
            outstring= outstring.."Eighty-"
            return outstring, remainder
        end
    elseif number / 10 >= 7 then
        local remainder = number % 10
        if remainder == 0 then
            outstring= outstring.."Seventy"
        else
            outstring= outstring.."Seventy-"
            return outstring, remainder
        end
    elseif number / 10 >= 6 then
        local remainder = number % 10
        if remainder == 0 then
            outstring= outstring.."Sixty"
        else
            outstring= outstring.."Sixty-"
            return outstring, remainder
        end
    elseif number / 10 >= 5 then
        local remainder = number % 10
        if remainder == 0 then
            outstring= outstring.."Fifty"
        else
            outstring= outstring.."Fifty-"
            return outstring, remainder
        end
    elseif number / 10 >= 4 then
        local remainder = number % 10
        if remainder == 0 then
            outstring= outstring.."Forty"
        else
            outstring= outstring.."Forty-"
            return outstring, remainder
        end
    elseif number / 10 >= 3 then
        local remainder = number % 10
        if remainder == 0 then
            outstring= outstring.."Thirty"
        else
            outstring= outstring.."Thirty-"
            return outstring, remainder
        end
    elseif number / 10 >= 2 then
        local remainder = number % 10
        if remainder == 0 then
            outstring= outstring.."Twenty"
        else
            outstring= outstring.."Twenty-"
            return outstring, remainder
        end
    else
        if number == 19 then
            outstring=outstring.."Nineteen"
        elseif number == 18 then
            outstring=outstring.."Eighteen"
        elseif number == 17 then
            outstring=outstring.."Seventeen"
        elseif number == 16 then
            outstring=outstring.."Sixteen"
        elseif number == 15 then
            outstring=outstring.."Fifteen"
        elseif number == 14 then
            outstring=outstring.."Fourteen"
        elseif number == 13 then
            outstring=outstring.."Thirteen"
        elseif number == 12 then
            outstring=outstring.."Twelve"
        elseif number == 11 then
            outstring=outstring.."Eleven"
        elseif number == 10 then
            outstring=outstring.."Ten"
        elseif number == 9 then
            outstring=outstring.."Nine"
        elseif number == 8 then
            outstring=outstring.."Eight"
        elseif number == 7 then
            outstring=outstring.."Seven"
        elseif number == 6 then
            outstring=outstring.."Six"
        elseif number == 5 then
            outstring= outstring .. "Five"
        elseif number == 4 then
            outstring=outstring.."Four"
        elseif number == 3 then
            outstring=outstring.."Three"
        elseif number == 2 then
            outstring=outstring.."Two"
        elseif number == 1 then
            outstring=outstring.."One"
        end
        return outstring, 0
    end
end

local words, leftOver = num2wordint(arg[1])
local i = 1
while i ~= 0 do
    local inword, inrem = num2wordint(leftOver)
    words = words .. inword
    if inrem == 0 then
        i = 0
    else
        leftOver = inrem
    end
end

print(words)

【问题讨论】:

  • 一年多以前我也写过同样的文章。请看gist.github.com/hjpotter92/…
  • @hjpotter92 - 有趣。您的代码为输入 0 提供了错误的结果(应返回字符串“零”)并为输入 100 崩溃。顺便说一句,(n % 10 > 0 and num[n % 10] or '') 可以简化为num[n % 10]
  • @hjpotter92 - 另一个注意事项:tens[0] 已定义但从未使用过。
  • @hjpotter92 - 它也在25上崩溃

标签: lua


【解决方案1】:

remainder0 时,函数num2wordint 不会返回任何内容。

肮脏而简单的解决方法是将每个 sn-p 转换为:

    if remainder == 0 then
        outstring= outstring.."Ninety"
    else
        outstring= outstring.."Ninety-"
        return outstring, remainder
    end

    if remainder == 0 then
        outstring= outstring.."Ninety"
    else
        outstring= outstring.."Ninety-"
    end
    return outstring, remainder

【讨论】:

    【解决方案2】:

    我对此的解决方案是忘记 if 语句,只做一些表索引。不过,我节省了一些空间,只是用一些基本值制定了一些简单的规则:

    local num2str
    do
       local bases = {[0]="","one","two","three","four","five","six","seven","eight","nine",[10]="ten",[11]="eleven",[12]="twelve",[13]="thirteen",[15]="fifteen",[20]="twenty",[30]="thirty",[40]="fourty",[50]="fifty",[60]="sixty",[70]="seventy",[80]="eighty",[90]="ninety"}
    
       function num2str(n)
          local s = tostring(n)
          if n < 20 then
             return bases[n] or bases[tonumber(s:sub(2,2))].."teen"
          else
             return bases[tonumber(s:sub(1,1))*10]..bases[tonumber(s:sub(2,2))]
          end
       end
    end
    
    for i = 1,99 do
       print(num2str(i))
    end
    

    【讨论】:

    • 另外,如果你使用字符串键,你可以消除 tonumber 调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 1970-01-01
    • 2021-09-18
    相关资源
    最近更新 更多