You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

卡诺图含通配符字符串高效展开的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))

实现说明

  1. 效率优势:避免了原代码中反复的深拷贝、列表增删操作——这些操作在数据量增大时会带来极大的时间和内存开销。itertools.product是C实现的迭代器,生成组合的效率远高于纯Python循环。
  2. 去重处理:如果多个带*的pattern展开后出现重复的最小项(比如*000和0*00都会生成0000),用set自动去重后转回列表即可。
  3. 示例验证:
    • 调用expand_wildcards(["*000", "0*00"])会返回['0000', '1000', '0100']
    • 调用expand_wildcards(["*11*"])会返回['0110', '0111', '1110', '1111']

内容的提问来源于stack exchange,提问作者Alenna Spiro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:57:23