0

所以仍在研究将数字转换为中文拼音的程序。完整代码(请原谅我的古怪,我真的很感谢所有对我糟糕编码的帮助)

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 的早期值吗?谢谢!

4

3 回答 3

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
于 2013-01-31T17:07:55.060 回答
2

逻辑没有错。要么cwords或未nlength正确初始化。

不过,代码有点不稳定。您每个循环都进行两次相同的测试,这应该是一个危险信号

你可以这样做:

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*$')
于 2013-01-31T17:36:40.233 回答
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)
于 2013-02-01T09:45:50.477 回答