简单的 LZW 压缩不起作用
Simple LZW Compression doesnt work
我写了简单的class来压缩数据。这是:
LZWCompressor = {}
function LZWCompressor.new()
local self = {}
self.mDictionary = {}
self.mDictionaryLen = 0
-- ...
self.Encode = function(sInput)
self:InitDictionary(true)
local s = ""
local ch = ""
local len = string.len(sInput)
local result = {}
local dic = self.mDictionary
local temp = 0
for i = 1, len do
ch = string.sub(sInput, i, i)
temp = s..ch
if dic[temp] then
s = temp
else
result[#result + 1] = dic[s]
self.mDictionaryLen = self.mDictionaryLen + 1
dic[temp] = self.mDictionaryLen
s = ch
end
end
result[#result + 1] = dic[s]
return result
end
-- ...
return self
end
我 运行 它由:
local compressor = LZWCompression.new()
local encodedData = compressor:Encode("I like LZW, but it doesnt want to compress this text.")
print("Input length:",string.len(originalString))
print("Output length:",#encodedData)
local decodedString = compressor:Decode(encodedData)
print(decodedString)
print(originalString == decodedString)
但是当我最终通过 lua 运行 它时,它表明解释器需要字符串,而不是 Table。那很奇怪,因为我传递了字符串类型的参数。为了测试 Lua 的日志,我在函数的开头写道:
print(typeof(sInput))
我得到输出 "Table" 和 lua 的错误。那么如何解决呢?为什么 lua 显示那个字符串(我已经通过)是 table?我使用 Lua 5.3.
问题出在方法 Encode() 的定义中,很可能 Decode() 也有同样的问题。
您使用点语法创建 Encode() 方法:self.Encode = function(sInput)
、
但是你用冒号语法调用它:compressor:Encode(data)
当您使用冒号语法调用 Encode() 时,它的第一个隐式参数将是 compressor
本身(table 来自您的错误),而不是数据。
要修复它,请使用冒号语法声明 Encode() 方法:function self:Encode(sInput)
,或显式添加 'self' 作为第一个参数 self.Encode = function(self, sInput)
您提供的代码根本不应该运行。
您定义 function LZWCompressor.new()
但调用 CLZWCompression.new()
在 Encode 中调用 self:InitDictionary(true)
尚未定义。
可能您没有在此处粘贴所有相关代码。
您收到错误的原因是您调用了 compressor:Encode(sInput)
,它等同于 compressor.Encode(self, sInput)
。 (语法糖)由于函数参数不是通过名称传递的,而是通过它们在 Encode 中的位置 sInput
现在是 compressor
,而不是您的字符串。
然后将您的第一个参数(恰好是 self
、table)传递给需要字符串的 string.len
。
所以你实际上调用了 string.len(compressor)
这当然会导致错误。
请确保您知道如何调用和定义函数以及如何正确使用 self!
我写了简单的class来压缩数据。这是:
LZWCompressor = {}
function LZWCompressor.new()
local self = {}
self.mDictionary = {}
self.mDictionaryLen = 0
-- ...
self.Encode = function(sInput)
self:InitDictionary(true)
local s = ""
local ch = ""
local len = string.len(sInput)
local result = {}
local dic = self.mDictionary
local temp = 0
for i = 1, len do
ch = string.sub(sInput, i, i)
temp = s..ch
if dic[temp] then
s = temp
else
result[#result + 1] = dic[s]
self.mDictionaryLen = self.mDictionaryLen + 1
dic[temp] = self.mDictionaryLen
s = ch
end
end
result[#result + 1] = dic[s]
return result
end
-- ...
return self
end
我 运行 它由:
local compressor = LZWCompression.new()
local encodedData = compressor:Encode("I like LZW, but it doesnt want to compress this text.")
print("Input length:",string.len(originalString))
print("Output length:",#encodedData)
local decodedString = compressor:Decode(encodedData)
print(decodedString)
print(originalString == decodedString)
但是当我最终通过 lua 运行 它时,它表明解释器需要字符串,而不是 Table。那很奇怪,因为我传递了字符串类型的参数。为了测试 Lua 的日志,我在函数的开头写道:
print(typeof(sInput))
我得到输出 "Table" 和 lua 的错误。那么如何解决呢?为什么 lua 显示那个字符串(我已经通过)是 table?我使用 Lua 5.3.
问题出在方法 Encode() 的定义中,很可能 Decode() 也有同样的问题。
您使用点语法创建 Encode() 方法:self.Encode = function(sInput)
、
但是你用冒号语法调用它:compressor:Encode(data)
当您使用冒号语法调用 Encode() 时,它的第一个隐式参数将是 compressor
本身(table 来自您的错误),而不是数据。
要修复它,请使用冒号语法声明 Encode() 方法:function self:Encode(sInput)
,或显式添加 'self' 作为第一个参数 self.Encode = function(self, sInput)
您提供的代码根本不应该运行。
您定义 function LZWCompressor.new()
但调用 CLZWCompression.new()
在 Encode 中调用 self:InitDictionary(true)
尚未定义。
可能您没有在此处粘贴所有相关代码。
您收到错误的原因是您调用了 compressor:Encode(sInput)
,它等同于 compressor.Encode(self, sInput)
。 (语法糖)由于函数参数不是通过名称传递的,而是通过它们在 Encode 中的位置 sInput
现在是 compressor
,而不是您的字符串。
然后将您的第一个参数(恰好是 self
、table)传递给需要字符串的 string.len
。
所以你实际上调用了 string.len(compressor)
这当然会导致错误。
请确保您知道如何调用和定义函数以及如何正确使用 self!