【发布时间】:2020-10-10 00:16:08
【问题描述】:
给定一个字符串,例如i am a string.
我可以像这样使用 nltk 包生成这个字符串的 n-gram,其中 n 是根据指定范围的变量。
from nltk import ngrams
s = 'i am a string'
for n in range(1, 3):
for grams in ngrams(s.split(), n):
print(grams)
给出输出:
('i',)
('am',)
('a',)
('string',)
('i', 'am')
('am', 'a')
('a', 'string')
有没有办法使用生成的 ngram 组合来“重构”原始字符串?或者,用下面评论者的话来说,有没有办法将句子分成连续的单词序列,其中每个序列的最大长度为 k(在这种情况下 k 为 2)。
[('i'), ('am'), ('a'), ('string')]
[('i', 'am'), ('a'), ('string')]
[('i'), ('am', 'a'), ('string')]
[('i'), ('am'), ('a', 'string')]
[('i', 'am'), ('a', 'string')]
这个问题与this 的问题类似,但更复杂。
工作解决方案 - 改编自 here。
我有一个可行的解决方案,但是对于较长的字符串,它真的很慢。
def get_ngrams(s, min_=1, max_=4):
token_lst = []
for n in range(min_, max_):
for idx, grams in enumerate(ngrams(s.split(), n)):
token_lst.append(' '.join(grams))
return token_lst
def to_sum_k(s):
for len_ in range(1, len(s.split())+1):
for i in itertools.permutations(get_ngrams(s), r=len_):
if ' '.join(i) == s:
print(i)
to_sum_k('a b c')
【问题讨论】:
-
基本上你使用它和一个累积和来找出你输入的所有可能的分割,这相当于你正在寻找的东西。
-
“类似于下面”不是很精确;你应该尽量使你的问题描述尽可能明确。您的意思是“将句子分成连续的单词序列,其中每个序列的最大长度为
k(在这种情况下k为2)”?或者你的意思是用所有可能的方式将句子分成一元和二元? -
嗨@rici,你一针见血。我已将问题更新为更具体。
-
@Andy 我的原始答案假设我们不知道原始字符串。我将添加一个新答案