【发布时间】:2020-02-08 01:51:19
【问题描述】:
我当前代码的一部分涉及(伪)随机生成相当多对不同长度的字符串 - 具体来说,
shiftspace = {
2: 20,
3: 79,
4: 250,
5: 791,
6: 2500,
7: 7906,
8: 25000,
9: 79059
}
其中 key = 字符串的长度和 value = 要生成的对。这些字符串可以由字符 0-9 的任何变体以及代表任何字符的字符 * 组成。问题在于我不希望这些集合包含任何重复。在我实现 * 之前,我只是检查了是否已经生成了一个新生成的数字,但是现在字符串可以“重叠”,尽管它们是不相同的。例如,“*056*3”的存在使生成的序列“*05693”或“905623”或“4056*3”无效
目前解决方案是我的老“朋友”正则表达式。我只是生成一个由 [char1*][char2*][char3*] 等组成的正则表达式字符串,它能够完美地挑选出这些匹配项。问题是速度——我检查每个条目的正则表达式,当达到更高的数字时,它会及时膨胀(要检查的最大可能集可以达到近 80k 条目)。过去需要 5 分钟 * 现在需要一个小时或更长时间。完成这一切的代码如下。
def regexfit(strang,set):
regex = ""
for char in strang:
regex = regex + "["+char+"*]"
match = re.search(regex,set)
if match:
return True
def shiftgen():
baseset = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "*"]
shiftset = {}
keys = list(shiftspace.keys())
togo = sum(shiftspace.values())
print(togo)
for i in range(min(keys), max(keys) + 1):
print(i)
shiftset[i] = {}
shiftset[i]["0"] = 0
for j in range(shiftspace[i]):
num = 0
num2 = 0
while num == num2:
num = np.random.choice(baseset, size=i)
num = "".join(num)
numset = [i for i in str(num)]
while any((regexfit(num,x) for x in shiftset[i].keys())):
num = np.random.choice(baseset, size=i)
num = "".join(num)
numset = [i for i in str(num)]
if len(str(num)) < i:
for k in range(i - len(str(num))):
numset.append(0)
num2 = np.random.choice(numset, size=i, replace=False)
num2 = "".join(num2)
shiftset[i][num] = num2
togo = togo - 1
if togo % 1000 == 0:
print([num, num2])
shiftset[i].pop("0")
return shiftset
我考虑过的事情:
连接所有序列以检查成一个巨大的字符串(使用分隔符 char 以防止正则表达式在两个序列之间匹配)并在其上使用正则表达式。我对 re 引擎的内部结构了解得不够多,不知道它最终会有多好。一旦我对上面代码的第一次定时测试完成后,我将测试它的运行速度。
将这些带星号的字符串作为它们可以采用的所有可能排列添加到数据库中(即:将 2* 添加为 21、22、23 等)>。然后您只需搜索数据库(或者,如果您生成带星号的字符串,则搜索每个排列并检查是否有正数)。我非常怀疑这会更有效,但你永远不知道。
某种解决方案,您可以在其中生成序列,确定它们之前没有生成过或者会被之前生成的序列“覆盖”,从而完全消除了搜索的需要。不是真正的解决方案,因为我不知道该怎么做,只是把它扔在那里。
某种更高级的正则表达式,计算速度更快。
某种神奇的模块/公式由于某种原因非常擅长做这件事。
黑魔法、祭祀上古之神等
TL:DR 我正在寻找一种更快的方法来匹配具有许多潜在排列的序列,以确保以前没有选择过排列。
【问题讨论】:
标签: python regex python-3.x