2016-05-10 9 views
1

Я написал простой класс для сжатия данных. Вот оно:Простой компрессия LZW не работает

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, это показывает, что интерпретатор ожидал строку, а не Таблица. Это было странно, потому что я передаю аргумент типа string. Для проверки журналов Lua, я писал beggining функции:

print(typeof(sInput)) 

я получил выходной «Таблица» и ошибка Lua в. Итак, как это исправить? Почему lua отображает эту строку (что я прошел) - это таблица? Я использую Lua 5.3.

+0

, пожалуйста, приложите больше усилий, чтобы решить эту проблему в следующий раз. «почему этот код не работает», вопросы, как правило, снижаются или удаляются на SO. Также я не могу просто запустить ваш код, чтобы увидеть, что происходит, поскольку вы не предоставляете надлежащее [MCVE]. Пожалуйста, прочитайте [ask] – Piglet

ответ

1

Проблема заключается в определении метода Encode(), и, скорее всего, Decode() имеет такую ​​же проблему.
Вы создаете метод Encode(), используя точечный синтаксис: self.Encode = function(sInput),
, но тогда вы вызываете его с двоеточием: compressor:Encode(data)
При вызове Encode() с двоеточием, его первый неявный аргумент будет compressor сами (таблица от вашей ошибки), а не данные.
Чтобы исправить это, объявить Encode() метод с двоеточием: function self:Encode(sInput), или добавить «я» в качестве первого аргумента явно self.Encode = function(self, sInput)

1

Код вы предоставили не должен работать на всех.

Вы определяете function LZWCompressor.new() но называть CLZWCompression.new()

Внутри Encode вы называете self:InitDictionary(true), который не был определен.

Возможно, вы не ввели все соответствующие коды здесь.

Причиной ошибки, которую вы получаете, является то, что вы вызываете compressor:Encode(sInput), что эквивалентно compressor.Encode(self, sInput). (синтаксический сахар) Поскольку функциональные параметры не передаются по имени, а по их позиции sInput внутри Encode теперь compressor, а не ваша строка. Ваш первый аргумент (который, оказывается, self, таблица) затем передается в string.len, который ожидает строку. Таким образом, вы вызываете string.len(compressor), что, конечно, приводит к ошибке.

Пожалуйста, убедитесь, что вы знаете, как звонить и определять функции и как правильно использовать себя!

+0

Я изменил CLZWCompression при вызове LZWCompression. –