lua重复/直到似乎使用原始值

时间:2013-01-31 15:48:40

标签: lua

所以仍然致力于将数字转换为中文拼音的程序。完整的代码(请原谅不稳定,我非常感谢我的错误编码的所有帮助)

local digitmap = {
   ["0"] = "ying2",
   ["1"] = "yi1",
   ["2"] = "er2",
   ["3"] = "san1",
   ["4"] = "si4",
   ["5"] = "wu3",
   ["6"] = "liu4",
   ["7"] = "qi1",
   ["8"] = "ba1",
   ["9"] = "jiu3",
}

print("Enter a number to be converted (up to 10 digits long):")

while true do
    number = tonumber(io.read("*line"))
    nlength = #(tostring(number))
    if number ~= nil and nlength <= 10 then
        break
    end
    print("Invalid input or too long. Please try again:")
end

if number == 0 then
fconvnumber = "ying2"
zero = true
end

local cwords = {}
for c in string.gmatch(number, "%d") do
cwords[#cwords + 1] = digitmap[c]
end

if nlength == 2 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
elseif nlength == 3 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
elseif nlength == 4 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
elseif nlength == 5 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
elseif nlength == 6 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
    cwords[nlength - 5] = cwords[nlength - 5] .. " shi2 "
elseif nlength == 7 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
    cwords[nlength - 5] = cwords[nlength - 5] .. " shi2 "
    cwords[nlength - 6] = cwords[nlength - 6] .. " bai3 "
elseif nlength == 8 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
    cwords[nlength - 5] = cwords[nlength - 5] .. " shi2 "
    cwords[nlength - 6] = cwords[nlength - 6] .. " bai3 "
    cwords[nlength - 7] = cwords[nlength - 7] .. " qian1 "
elseif nlength == 9 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
    cwords[nlength - 5] = cwords[nlength - 5] .. " shi2 "
    cwords[nlength - 6] = cwords[nlength - 6] .. " bai3 "
    cwords[nlength - 7] = cwords[nlength - 7] .. " qian1 "
    cwords[nlength - 8] = cwords[nlength - 8] .. " yi4 "
elseif nlength == 10 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
    cwords[nlength - 5] = cwords[nlength - 5] .. " shi2 "
    cwords[nlength - 6] = cwords[nlength - 6] .. " bai3 "
    cwords[nlength - 7] = cwords[nlength - 7] .. " qian1 "
    cwords[nlength - 8] = cwords[nlength - 8] .. " yi4 "
    cwords[nlength - 9] = cwords[nlength - 9] .. " shi2 "
end

while cwords[nlength] == "ying2" and zero ~= true do
    cwords[nlength] = nil
    nlength = nlength - 1
end

fconvnumber = table.concat(cwords)

fconvnumber = string.gsub(fconvnumber, "ying2 %a+%d", "ying2")
for i=1,nlength do
    fconvnumber = string.gsub(fconvnumber, "ying2 ying2", "ying2")
end
fconvnumber = string.gsub(fconvnumber, "yi1 shi2", "shi2")

print(fconvnumber)

所以,例如,如果我输入100,nlength是3,cwords [nlength] ==“ying2”,它会删除最后一个数组。但它不会再次循环并删除十位0.我知道我必须以某种方式忽略逻辑,但我只是没有看到它。直到使用nlength的早期valua?谢谢!

3 个答案:

答案 0 :(得分:2)

由于您没有提供完整的代码,因此很难说,但我怀疑您没有正确填充cwords,因为我没有在您发布的代码中看到问题。这对我有用:

cwords = {1, "ying2", "ying2"}
nlength = #cwords
print("started with", #cwords)
repeat
if cwords[nlength] == "ying2" then
    cwords[nlength] = nil
    nlength = nlength - 1
end
until cwords[nlength] ~= "ying2"
print("ended with", #cwords)

您可能希望将此更改为while循环,因为逻辑更简单:

while nlength > 0 and cwords[nlength] == "ying2" do
    cwords[nlength] = nil
    nlength = nlength - 1
end

答案 1 :(得分:2)

逻辑没有错。 cwordsnlength未正确初始化。

但是,代码有点不稳定。你在每个循环中进行两次相同的测试,应该是a red flag

你可以这样做:

while cwords[nlength] == "ying2" do
    cwords[nlength] = nil
    nlength = nlength - 1
end

或者像这样:

while cwords[#cwords] == "ying2" do
    table.remove(cwords)
end

但最有效的方法是在转换为拼音之前从源编号中删除尾随零:

while number % 10 == 0 do
    number = number / 10
end

或者:

strnumber = strnumber:match('(.-)0*$')

答案 2 :(得分:1)

编辑:最后看,我帮你解决实际问题......

关于更新后代码的一些事项:

1)您在数字上使用gmatch,而不是字符串。

它只能因为强制而起作用,这不是一个好主意。您可以通过使用OO样式的调用来确保:

for c in number:gmatch("%d") do

它会破坏这个错误:

attempt to index global 'number' (a number value)

您应该保留该数字的字符串版本,如下所示:

while true do
    number = tonumber(io.read("*line"))
    str_number = tostring(number)
    nlength = #str_number
    if number ~= nil and nlength <= 10 then
        break
    end
    print("Invalid input or too long. Please try again:")
end

if number == 0 then
    fconvnumber = "ying2"
    zero = true
end

local cwords = {}
for c in str_number:gmatch("%d") do
    cwords[#cwords + 1] = digitmap[c]
end

2)这部分非常重复:

if nlength == 2 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
elseif nlength == 3 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
elseif nlength == 4 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
elseif nlength == 5 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
elseif nlength == 6 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
    cwords[nlength - 5] = cwords[nlength - 5] .. " shi2 "
elseif nlength == 7 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
    cwords[nlength - 5] = cwords[nlength - 5] .. " shi2 "
    cwords[nlength - 6] = cwords[nlength - 6] .. " bai3 "
elseif nlength == 8 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
    cwords[nlength - 5] = cwords[nlength - 5] .. " shi2 "
    cwords[nlength - 6] = cwords[nlength - 6] .. " bai3 "
    cwords[nlength - 7] = cwords[nlength - 7] .. " qian1 "
elseif nlength == 9 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
    cwords[nlength - 5] = cwords[nlength - 5] .. " shi2 "
    cwords[nlength - 6] = cwords[nlength - 6] .. " bai3 "
    cwords[nlength - 7] = cwords[nlength - 7] .. " qian1 "
    cwords[nlength - 8] = cwords[nlength - 8] .. " yi4 "
elseif nlength == 10 then
    cwords[nlength - 1] = cwords[nlength - 1] .. " shi2 "
    cwords[nlength - 2] = cwords[nlength - 2] .. " bai3 "
    cwords[nlength - 3] = cwords[nlength - 3] .. " qian1 "
    cwords[nlength - 4] = cwords[nlength - 4] .. " wan2 "
    cwords[nlength - 5] = cwords[nlength - 5] .. " shi2 "
    cwords[nlength - 6] = cwords[nlength - 6] .. " bai3 "
    cwords[nlength - 7] = cwords[nlength - 7] .. " qian1 "
    cwords[nlength - 8] = cwords[nlength - 8] .. " yi4 "
    cwords[nlength - 9] = cwords[nlength - 9] .. " shi2 "
end

您可以通过以下方式替换整个区块:

local suffixes = {"shi2","bai3","qian1","wan2","shi2","bai3","qian1","yi4","shi2"}
for i=1,nlength-1 do
    cwords[nlength - i] = string.format("%s %s ", cwords[nlength - i], suffixes[i])
end

3)这没用:

if number == 0 then
    fconvnumber = "ying2"
    zero = true
end

你设置fconvnumber但是你会在以后的行中重新设置它:

fconvnumber = table.concat(cwords)

零测试仅在while循环中使用一次:

while cwords[nlength] == "ying2" and zero ~= true do
    cwords[nlength] = nil
    nlength = nlength - 1
end

此外,您每次迭代都会重复测试。您可以删除第一个块并写入:

if number ~= 0 then
    while cwords[nlength] == "ying2" do
        cwords[nlength] = nil
        nlength = nlength - 1
    end
end

最终您的重构代码如下所示:

local digitmap = {
    ["0"] = "ying2",
    ["1"] = "yi1",
    ["2"] = "er2",
    ["3"] = "san1",
    ["4"] = "si4",
    ["5"] = "wu3",
    ["6"] = "liu4",
    ["7"] = "qi1",
    ["8"] = "ba1",
    ["9"] = "jiu3",
}

print("Enter a number to be converted (up to 10 digits long):")

while true do
    number = tonumber(io.read("*line"))
    str_number = tostring(number)
    nlength = #str_number
    if number ~= nil and nlength <= 10 then
        break
    end
    print("Invalid input or too long. Please try again:")
end

local cwords = {}
for c in str_number:gmatch("%d") do
    cwords[#cwords + 1] = digitmap[c]
end

local suffixes = {"shi2","bai3","qian1","wan2","shi2","bai3","qian1","yi4","shi2"}
for i=1,nlength-1 do
    cwords[nlength - i] = string.format("%s %s ", cwords[nlength - i], suffixes[i])
end

if number ~= 0 then
    while cwords[nlength] == "ying2" do
        cwords[nlength] = nil
        nlength = nlength - 1
    end
end

fconvnumber = table.concat(cwords)

fconvnumber = string.gsub(fconvnumber, "ying2 %a+%d", "ying2")
for i=1,nlength do
    fconvnumber = string.gsub(fconvnumber, "ying2 ying2", "ying2")
end
fconvnumber = string.gsub(fconvnumber, "yi1 shi2", "shi2")

print(fconvnumber)

可能仍有一些事情可以改进,但这已经很简单了:)

现在让我们解决真正的问题!

你说:

  

所以,例如,如果我输入100,nlength是3,cwords [nlength] ==   “ying2”,它删除最后一个数组。但它并没有循环   再次删除十位0.我知道我必须错过逻辑   不知何故,但我只是没有看到它。

那是因为第一次迭代后数组的最后一个元素不是“ying2”,而是“ying2 shi2”!想一想,你早些时候已经联系了“shi2”。

现在的问题是:你期待的结果是“yi1 bai3”还是“yi1”?

如果是“yi1”,只需在连接之前消除零。如果是“yi1 bai3”,请执行以下操作:

local suffixes = {"shi2","bai3","qian1","wan2","shi2","bai3","qian1","yi4","shi2"}
cwords[nlength] = {cwords[nlength]}
for i=1,nlength-1 do
    cwords[nlength - i] = {cwords[nlength - i],string.format(" %s ",suffixes[i])}
end

if number ~= 0 then
    while cwords[nlength][1] == "ying2" do
        cwords[nlength] = nil
        nlength = nlength - 1
    end
end

for i=1,nlength do
    cwords[i] = table.concat(cwords[i])
end

fconvnumber = table.concat(cwords)