如何在随机生成的算术等式字符串中随机插入一组或多组括号?
给随机等式插入随机括号的最简实现方案
嘿,这个需求其实挺有意思的!核心思路是先把表达式拆成数字和运算符的“原子单元”,然后找出所有能加括号的合法区间,再随机选几个区间插入括号就行。我给你写个简洁的实现,直接就能用:
首先,我们需要把生成的等式字符串拆分成数字和运算符的列表,这样方便定位括号要插入的位置。然后找出所有可能的括号包裹区间,随机选1到2组(你可以自己调整数量),最后把括号插进去拼接成新字符串。
import random import re def add_random_parentheses(expr): # 把表达式拆成数字和运算符的列表,比如"1-2*3-4"会变成['1', '-', '2', '*', '3', '-', '4'] tokens = re.findall(r'\d+|[+\-*/]', expr) # 找出所有数字在tokens中的索引位置 num_positions = [idx for idx, token in enumerate(tokens) if token.isdigit()] num_count = len(num_positions) # 如果表达式只有1个数字,没法加括号,直接返回原字符串 if num_count < 2: return expr # 生成所有合法的括号包裹区间:(起始数字索引, 结束数字索引),起始必须小于结束 possible_ranges = [] for start_num_idx in range(num_count): for end_num_idx in range(start_num_idx + 1, num_count): possible_ranges.append((start_num_idx, end_num_idx)) # 随机选1到2组括号(你可以改成random.randint(1, len(possible_ranges))来允许更多组) num_paren_groups = random.randint(1, min(2, len(possible_ranges))) selected_ranges = random.sample(possible_ranges, num_paren_groups) # 按结束数字的索引从大到小排序,这样插入括号时不会因为前面的插入打乱后面的索引 selected_ranges.sort(key=lambda x: -x[1]) for start_num, end_num in selected_ranges: # 找到对应的tokens插入位置:在起始数字前加'(', 结束数字后加')' insert_open_at = num_positions[start_num] insert_close_at = num_positions[end_num] + 1 # 因为要插在结束数字后面,所以是原位置+1 # 注意:插入'('后,后面的元素索引会+1,所以插入')'时要额外加1 tokens.insert(insert_open_at, '(') tokens.insert(insert_close_at + 1, ')') return ''.join(tokens) # 测试一下 if __name__ == "__main__": test_expr = "1-2*3-4" for _ in range(5): print(add_random_parentheses(test_expr))
代码说明:
- 拆分表达式:用正则
re.findall(r'\d+|[+\-*/]'精准拆分数字和运算符,不管数字是一位还是多位都能处理。 - 生成合法区间:比如4个数字的表达式,能生成
(0,1)(包裹1-2)、(1,3)(包裹2*3-4)等所有连续数字组合,保证括号包裹的是合法的子表达式。 - 避免索引混乱:从后往前插入括号,这样前面插入的括号不会影响后面要插入的位置,不会出现括号插错地方的情况。
- 灵活调整:你可以修改
num_paren_groups的范围,比如允许最多3组括号,或者去掉min(2, ...)让它能选所有可能的区间(不过太多括号会让表达式变得很复杂)。
举几个运行后的输出例子:
(1-2)*(3-4) (1-2*3)-4 1-(2*3-4) (1-(2*3))-4 1-(2*(3-4))
完全符合你要的随机插入括号的需求,而且代码逻辑清晰,改起来也方便~
内容的提问来源于stack exchange,提问作者Miklath
相关产品推荐
相关产品推荐

