String Lua:迭代给定符号列表的每个可能的k长度字符串

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长度字符串(称为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 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