通常需要处理一系列“块”,这些“块”是从“原子”流中读取的,其中每个块由可变数量的原子组成,并且程序无法知道它具有收到一个完整的块,直到它读取下一个块的第一个原子(或原子流变得耗尽)。
执行此任务的简单算法如下所示:
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”(并以'&gt;'作为其第一个字符区分),然后是包含多段核苷酸或蛋白质序列的可变数目的行。同样,代码只有在读取下一个块的第一个原子(即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
答案 0 :(得分:2)
我唯一能想到的是它是一个非常简单的LL(1)解析器。您正在从左到右解析(以非常简单的方式)数据,您需要预测一个值以了解正在发生的事情。见http://en.wikipedia.org/wiki/LL_parser
答案 1 :(得分:1)
在索引中聚合简单统计信息时,我会定期实现此模式(尤其是与排序结合使用)。我从未听说过正式名称,但在我们公司内部,我们只是在SQL GROUP BY
子句之后将其称为“批处理”或“分组”。
在我们的系统中,批处理通常由提取的属性(而不是光头边缘驱动的谓词)分隔,我们称之为批处理或组密钥。相比之下,您的示例似乎检查了明确的分隔符。
答案 2 :(得分:1)
我相信您所描述的内容称为 streaming algorithm ,这是一种算法,其中输入一次指定一个元素,直到触发某个停止条件。流式算法可用于对通过网络或从生成数据的某个设备接收数据的算法进行建模。通常,流式算法假设在任何时间点都可以存储的内存量有一定的固定界限,这意味着算法需要特别注意保留重要信息,同时丢弃无用数据。
计算机科学中许多有趣的算法无法在流媒体案例中工作,并且有一大类专门设计用于流的算法。例如,有很好的流式算法用于查找流的前k个元素(例如,参见this question),用于从流中随机选择k个元素,以查找在流中以高频率出现的元素这个问题的另一个答案之一(来自@andrew cooke)提到这类似于LL解析。实际上,LL解析(以及许多其他解析算法,例如LR解析)是用于进行解析的流算法,但它们是更通用的流算法框架的特殊情况。
希望这有帮助!