通过从第一个字符串重复x个字符来获取所需的所有字符串

时间:2017-05-23 14:11:38

标签: python python-2.7

我们说我有以下字符串:

string = '---A---B-C'

我有以下词典:

min_max_values = {'A': [2,4], 'B': [2, 15], 'C': [1, 2]}

我的目标是从第一个字符串生成新字符串:

  • 所有新字符串必须与预定义的长度匹配

  • 所有角色组必须用相同数量的' - '作为原始字符串

  • 只能重复dict中的字符,但可以重复的最小和最长时间([min,max])。例如,' A'必须使用至少2次,但最多使用4次。

这是一个让自己清楚的例子:

string = '---A---B-C'
min_max_values = {'A': [2,4], 'B': [2, 15], 'C': [1, 2]}

wanted_length = 20

Outputs :
'---AAAA---BBBBBBBB-C'
'---AAAA---BBBBBBB-CC'
'---AAA---BBBBBBBBB-C'
'---AAA---BBBBBBBB-CC'
'---AA---BBBBBBBBBB-C'
'---AA---BBBBBBBBB-CC'

我可以看到我只能用一个角色,也许两个角色来做到这一点,但我完全不知道如何处理所有组合!有什么想法吗?

修改

@AChampion让我在评论中显示代码并解释我遇到的问题。

所以,这是我当前的代码(new_strings是我的最终输出) - 如果你想要复制并粘贴它,它就完全正常了 -

import re

string = '---A---B-C'
split_string = re.findall('-*', string)
characters = re.findall('[A-Z]', string)
min_max_values = {'A': [2,4], 'B': [2, 15], 'C': [1, 2]}
wanted_length = 20
combinations = get_combinations(string, min_max_values, wanted_length)
new_strings = []

for combination in combinations:
    new_string = ''
    character_index = 0
    for chunk in cut_string:
        print new_string
        if chunk:
            new_string += chunk
        elif character_index < len(characters):
            character = characters[character_index]
            new_string += character*combination[character]
            character_index += 1
    new_strings.append(new_string)


def get_combinations(string, min_max_values, wanted_length):
    constant_length = string.count('-') # 7
    remaining_length = wanted_length - constant_length # 13
    # What I want to do : find combinations that will add up to the remaining_length
    # i.e. : combinations = [{'A': 4, 'B': 8, 'C': 1}, {'A': 4, 'B': 7, 'C': 2}, {'A': 3, 'B': 9, 'C': 1}, {'A': 3, 'B': 8, 'C': 2}, {'A': 2, 'B': 10, 'C': 1}, {'A': 2, 'B': 9, 'C': 2}]
    combinations = [{'A': 4, 'B': 8, 'C': 1}, {'A': 4, 'B': 7, 'C': 2}, {'A': 3, 'B': 9, 'C': 1}, {'A': 3, 'B': 8, 'C': 2}, {'A': 2, 'B': 10, 'C': 1}, {'A': 2, 'B': 9, 'C': 2}]
    return combinations

而且我被困在&#34;组合&#34;。我不知道如何自动生成这个词。我想将这三个值相加,以便它们与剩余长度相匹配,但我不知道该怎么做。我更大的问题是这个方法必须处理原始字符串中的任意数量的字符(例如--- A ---- B --- D --- E - F --- G)。唯一给出的是字符串只包含破折号和字符;并且字符将始终位于min_max_values dict中。

我没有把这个代码放在第一位,因为即使我的其余代码看起来也错了。我对任何输入/改进持开放态度。

1 个答案:

答案 0 :(得分:1)

您可以使用itertools.product()生成'A''B'的组合,然后从您想要的字符串长度中减去,看看您是否适合'C'。在range()上操作更容易,因此快速的字典理解可以将min_max_values变为一组ranges

import itertools as it

dashes = string.count('-')
ranges = {k: range(v[0], v[1]+1) for k, v in min_max_values.items()}
for a, b in it.product(ranges['A'], ranges['B']):
    c = wanted_length - dashes - a - b
    if c in ranges['C']:
        print('---{}---{}-{}'.format('A'*a, 'B'*b, 'C'*c))

输出:

---AA---BBBBBBBBB-CC
---AA---BBBBBBBBBB-C
---AAA---BBBBBBBB-CC
---AAA---BBBBBBBBB-C
---AAAA---BBBBBBB-CC
---AAAA---BBBBBBBB-C

将其转换为词典列表:

results = []
for a, b in it.product(ranges['A'], ranges['B']):
    c = wanted_length - dashes - a - b
    if c in ranges['C']:
        results.append({'A': a, 'B': b, 'C': c})
print(results)

输出:

[{'A': 2, 'B': 9, 'C': 2},
 {'A': 2, 'B': 10, 'C': 1},
 {'A': 3, 'B': 8, 'C': 2},
 {'A': 3, 'B': 9, 'C': 1},
 {'A': 4, 'B': 7, 'C': 2},
 {'A': 4, 'B': 8, 'C': 1}]

您可以it.product(ranges['A'], ranges['B'], ranges['C'])获得相同的结果但效率稍低:

[{'A':a, 'B':b, 'C':c} for a, b, c in it.product(ranges['A'], ranges['B'], ranges['C']) if a+b+c=20-dashes]