Lua中BWT的快速实现
2016-5-14 15:18:24
收藏:0
阅读:61
评论:1
local function fShallowCopy(tData)
local tOutput = {}
for k,v in ipairs(tData) do
tOutput[k] = v
end
return tOutput
end
local function fLexTblSort(tA,tB) --这是用于表排序的函数
for i=1,#tA do
if tA[i]~=tB[i] then
return tA[i]<tB[i]
end
end
return false
end
function fBWT(tData)
--初始化--
local iSize = #tData
local tSolution = {}
local tSolved = {}
--关键表--
for n=1,iSize do
tData[iSize] = fRemove(tData,1)
tSolution[n] = fShallowCopy(tData)
end
table.sort(tSolution,fLexTblSort)
--编码输出--
for i=1,iSize do
tSolved[i] = tSolution[i][iSize]
end
--完成--
for i=1,iSize do
if fIsEqual(tSolution[i],tData) then
return i,tSolved
end
end
return false
end
上面是我目前用 Lua 实现 BWT 编码的代码。问题在于由于表的大小和循环的长度,运行时间很长。对于一个 1000 个字符的输入,平均编码时间约为 1.15 秒。有人有更快的 BWT 编码函数的建议吗?
最大的减速似乎出现在 fLexTblSort 和 fShallowCopy 中。我已经将它们都包括在 BWT 函数的上方。
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
如果我没看错的话,你的算法在快速排序的情况下的复杂度是
O(n^2 log n)。comparator函数fLexTblSort本身对于比较的每一对数值都需要O(n)的时间。经过我几年前的实现检查,我发现可以改进的空间。你创建了所有可能的
tData的旋转,这也需要很长时间。我只使用了单个数据块,并只存储了特定旋转的起始位置。你还使用了很多循环,可以缩小到更少。我的实现是用C语言的,但这个概念也可以用在Lua中。这是一种在你的Lua和C之间混合的伪代码。
function fBWT(tData) local n = #tData local tSolution = {} for(i = 0; i < n; i++) tSolution[i] = i; --table.sort(tSolution, fLexTblSort) quicksort(tData, n, tSolution, 0, n) for(i = 0; i < n; i++){ tSolved[i] = tData[(tSolution[i]+n-1)%n]; if( tSolution[i] == 0 ) I = i; } return I, tSolved end你还需要自己的排序函数,因为标准不提供足够的灵活性用于这种魔法。快速排序是一个不错的选择(你可能可以避免一些参数,但我只是贴上了我使用的C版本):
void swap(int array[], int left, int right){ int tmp = array[right]; array[right] = array[left]; array[left] = tmp; } void quicksort(uint8_t data[], int length, int array[], int left, int right){ if(left < right){ int boundary = left; for(int i = left + 1; i < right; i++){ if( offset_compare(data, length, array, i, left) < 0 ){ swap(array, i, ++boundary); } } swap(array, left, boundary); quicksort(data, length, array, left, boundary); quicksort(data, length, array, boundary + 1, right); } }最后一步是你自己的比较函数(类似于你最初的函数,但是在旋转上工作,仍然是C语言):
/** * compare one string (fixed length) with different rotations. */ int offset_compare(uint8_t *data, int length, int *array, int first, int second){ int res; for(int i = 0; i < length; i++){ res = data[(array[first]+i)%length] - data[(array[second]+i)%length]; if( res != 0 ){ return res; } } return 0; }这是我几年前想出的基本思路,对我来说工作得很好。如果有什么不清楚或错误的地方,请让我知道。