卡诺图含通配符字符串高效展开的Python实现方案问询
高效展开卡诺图通配符字符串为最小项列表
我正在给卡诺图求解器做真值表生成模块——求解器接收4位字符串形式的ABCD变量设置(范围从"0000"到"1111")作为最小项,但输出的是带*的字符串(比如*000),*代表该位置的变量在最终方程中被消去。
需求是把这类带*的字符串列表展开成完整的无通配符字符串列表:
- 示例1:
["*000", "0*00"]→["0000", "1000", "0100"] - 示例2:
["*11*"]→["0110", "0111", "1110", "1111"]
当前用while循环实现,但效率极低:处理1000组数据集时,前430组速度正常,之后因序列复杂度上升速度骤降,整个过程耗时至少10分钟。已确认问题不在卡诺图求解器本身(它处理相同复杂度序列的速度极快)。
现有代码如下:
import copy ast = True while ast: new_string_result = copy.deepcopy(string_result) for i in range(len(string_result)): for c, char in enumerate(string_result[i]): if char == "*": # 替换为0和1 new_string_result.append(string_result[i][:c] + "0" + string_result[i][c+1:]) new_string_result.append(string_result[i][:c] + "1" + string_result[i][c+1:]) if "*" in string_result[i]: # 移除原始字符串(即使有多个*也只删一次) # print("Removing ", string_result[i]) new_string_result.remove(string_result[i]) # print("Kmap result during fix iter: ", new_string_result) ast_found = False for i in range(len(new_string_result)): if "*" in new_string_result[i]: ast_found = True # print(ast_found) ast = ast_found string_result = new_string_result
高效Python实现方案
利用itertools.product直接生成所有可能的组合,无需循环迭代替换,代码更简洁且效率大幅提升:
import itertools def expand_wildcards(patterns): expanded = [] for pattern in patterns: # 把每个字符转换为可选列表:*对应['0','1'],其他字符对应单元素列表 options = [['0', '1'] if c == '*' else [c] for c in pattern] # 生成所有组合并拼接成字符串 for combo in itertools.product(*options): expanded.append(''.join(combo)) # 去重(如果不同pattern展开后有重复项) return list(set(expanded))
实现说明
- 效率优势:避免了原代码中反复的深拷贝、列表增删操作——这些操作在数据量增大时会带来极大的时间和内存开销。
itertools.product是C实现的迭代器,生成组合的效率远高于纯Python循环。 - 去重处理:如果多个带
*的pattern展开后出现重复的最小项(比如*000和0*00都会生成0000),用set自动去重后转回列表即可。 - 示例验证:
- 调用
expand_wildcards(["*000", "0*00"])会返回['0000', '1000', '0100'] - 调用
expand_wildcards(["*11*"])会返回['0110', '0111', '1110', '1111']
- 调用
内容的提问来源于stack exchange,提问作者Alenna Spiro
相关产品推荐
相关产品推荐

