通常需要处理一系列的“块”,这些“块”是从“原子”流中读取的,其中每个块由不同数量的原子组成,程序无法知道它已经接收到一个完整的块,直到它读取下一个块的第一个原子(或原子流耗尽)。
执行此任务的简单算法如下:
LOOP FOREVER:
SET x TO NEXT_ATOM
IF DONE(x) OR START_OF_CHUNK(x):
IF NOT EMPTY(accum):
PROCESS(accum)
END
if DONE(x):
BREAK
END
RESET(accum)
END
ADD x TO accum
END
所以,我的问题是:
这个一般问题类和/或上面显示的编程模式有名字吗?
本文的其余部分只是上面抽象描述的几个(相当现实的)例子。(这些例子是用Python编写的,尽管它们可以很容易地翻译成任何命令式语言。)
第一个是生成输入字符串的运行长度编码的函数在这种情况下,“原子”是单个字符,而“块”是同一字符的最大值。因此,程序在读取下一次运行中的第一个字符之前,不会知道它已经到达运行的末尾。
def rle(s):
'''Compute the run-length encoding of s.'''
n = len(s)
ret = []
accum = 0
v = object() # unique sentinel; ensures first test against x succeeds
i = 0
while True:
x = s[i] if i < n else None
i += 1
if x is None or x != v:
if accum > 0:
ret.append((accum, v))
if x is None:
break
accum = 0
v = x
accum += 1
return ret
第二个例子是一个函数,它将fasta格式文件的读取句柄作为参数,并解析其内容。在这种情况下,原子是文本行每个片段由一个特别标记的第一行组成,称为“defline”(并以“>”作为其第一个字符加以区分),然后是包含核苷酸或蛋白质序列延伸的可变行数。同样,只有在读取下一个块的第一个原子(即defline)之后,代码才能毫不含糊地检测出块的结尾。
def read_fasta(fh):
'''Read the contents of a FASTA-formatted file.'''
ret = []
accum = []
while True:
x = fh.readline()
if x == '' or x.startswith('>'):
if accum:
ret.append((accum[0], ''.join(accum[1:])))
if x == '':
break
accum = []
accum.append(x.strip())
return ret
最佳答案
我唯一能想到的是它是一个非常简单的ll(1)解析器。您正在从左到右解析(以非常简单的方式)数据,您需要查看一个值以了解发生了什么。见http://en.wikipedia.org/wiki/LL_parser