String Lua:迭代给定符号列表的每个可能的k长度字符串
我希望在给定符号列表的情况下遍历每个可能的k长度字符串(称为k-mer)。例如,如果String Lua:迭代给定符号列表的每个可能的k长度字符串,string,lua,permutation,bioinformatics,String,Lua,Permutation,Bioinformatics,我希望在给定符号列表的情况下遍历每个可能的k长度字符串(称为k-mer)。例如,如果k=3和symbols={A,C,G,T},则: AAA AAC AAG ... TTG TTT 以下是生成字符串的代码: local k = 3 local bases = {'A', 'C', 'T', 'G'} -- Generate the string (AAA...AAA) local kmer_gen = {} for i = 1,k do kmer_gen[i] = "A" end local
k=3
和symbols={A,C,G,T}
,则:
AAA
AAC
AAG
...
TTG
TTT
以下是生成字符串的代码:
local k = 3
local bases = {'A', 'C', 'T', 'G'}
-- Generate the string (AAA...AAA)
local kmer_gen = {}
for i = 1,k do kmer_gen[i] = "A" end
local kmer = table.concat(kmer_gen)
它能起作用,但看起来肯定不好。这能更优雅地实现吗
现在,我不确定如何迭代可能的k-mers。一种解决方案是继续替换每个字符,但这并不有效。另一种方法是从二进制(每2位代表一个基数)解码,但实现过程很混乱,需要按位操作。还有其他想法吗?下面是一个相对简单的尾部递归解决方案,我可能会用到:
local bases = {'A', 'C', 'T', 'G'}
local function kmers(n, prev)
prev = prev or {''}
if n <= 0 then return prev end
local k,r = 1,{}
for i=1,#prev do
for j=1,#bases do
r[k] = prev[i] .. bases[j]
k = k+1
end
end
return kmers(n-1, r)
end
_3mers = kmers(3) -- usage example
localbase={'A','C','T','G'}
本地函数kmers(n,上一个)
prev=prev或{'}
如果n这里有一个使用迭代器的解决方案。这是协同程序的一个很好的例子,这是一种在Lua中非常值得了解的技术。另见
您是否测量过“明显更快”?例如,在我运行的机器上,公里数(11)的速度大约为15%(7.23s/8.57s)。考虑到变化的简单性,我认为这是值得的。您的解决方案速度更快(6.05秒,无需打印)。感谢您的计时。注意:如果我用local t={}替换您的解决方案的最后一行;对于kmer(11,基数)中的w,请执行t[#t+1]=w end
,以生成一个实际表,该表的射程为11.41s。有了这个:localk,t=1,{};对于kmer(11,基)中的w,t[k]=w;k=k+1端
10.02s。上一次计时是使用空的do/end
块进行的。此外,所有使用Lua 5.1.5而不是5.2的计时。
local bases = {'A', 'C', 'T', 'G'}
local function allstrings(n,t,k,s)
k=k or 1
s=s or {}
if k>n then
coroutine.yield(table.concat(s))
else
for i=1,#t do
s[k]=t[i]
allstrings(n,t,k+1,s)
end
end
end
local function kmer(n,t)
return coroutine.wrap(allstrings),n,t
end
for w in kmer(3,bases) do
print(w)
end