【问题标题】:Combinations of a pattern satisfying given constraints满足给定约束的模式组合
【发布时间】:2018-07-26 04:12:21
【问题描述】:

给出了由 1 和 0 组成的模式。它总是 7 位,3 位是 1,4 位是 0

示例 - 1100010

约束是一次考虑 2 个 0 并用 1 替换它们。我需要找到所有这些可能的组合。

到目前为止,我的想法是,找到 0 的索引并运行 for 循环以在每次运行时选择 2 个索引并获取输出。

示例 -

给定模式 - 1100010

所需的输出 -1111010、1110110、1110011、1101110、1101011、1100111

我可以详尽无遗地做到这一点。任何以更优化的方式执行此操作的建议都会非常有帮助。

【问题讨论】:

    标签: algorithm sorting combinations


    【解决方案1】:

    您的问题归结为找到 4 选择 2 的所有组合。您获取零索引的想法是一个很好的起点。

    对于给定的示例1100010,我们有以下内容:

    1 1 0 0 0 1 0
    | | | | | | |
    V V V V V V V 
    0 1 2 3 4 5 6   // indices here assuming base 0
    

    因此我们的零索引向量是{2, 3, 4, 6}

    现在,我们可以生成我们的零索引向量选择 2 的所有组合(在 SO 或网络上有几种很好的算法),并进行适当的替换以生成我们的输出。

    伪代码:

    inputVec = {1,1,0,0,0,1,0}
    zeroIndex = {}
    
    for i in 0 to (length(inputVec) - 1)
        if (inputVec[i] == 0)
            zeroIndex.push_back(i)     // zeroIndex = {2, 3, 4, 6} for the given example
    
    // initialize output vector to the input vector
    newOutput = inputVec
    myCombos = generateCombos(zeroIndex, 2) // matrix of combinations with 2 columns
    
    for i in 0 to (length(myCombos) - 1) {
        newOutput[myCombos[i, 0]] = 1
        newOutput[myCombos[i, 1]] = 1
        print(newOutput)
    
        // reset output vector
        newOutput = inputVec
    }
    

    在上述算法中,generateCombos 将输出以下内容:

         [,0] [,1]
    [0,]    2    3
    [1,]    2    4
    [2,]    2    6
    [3,]    3    4
    [4,]    3    6
    [5,]    4    6
    

    概述的算法扩展到输入向量具有任意长度并且具有任意数量的 0 和 1 的一般情况。

    【讨论】:

    • 非常感谢@JosephWood
    • @Paddy3118 我也理解你的代码。非常感谢。
    【解决方案2】:
    1. 查找输入中的四个零的位置并编号它们的位位置。
    2. 暂时忽略输入中零的位置,您有四个零将变成两个零和两个一。
    3. 按顺序查找“0011”的唯一排列集。
    4. 对于每个 perm:将 1 和 0 替换为原始数字中仅零的原始位置,以产生一个输出。

    类似:

    from itertools import permutations
    from pprint import pprint as pp
    
    unique_perms = set(permutations('0011'))
    
    num = input('number: ').strip()  # Keep as text
    for perm in unique_perms:
        out = []
        p = list(perm)
        for bit in num:
            out.append(bit if bit == '1' else p.pop())
        print('->', ''.join(out))
    

    示例运行:

    number: 1100010
    -> 1111010
    -> 1101110
    -> 1110110
    -> 1100111
    -> 1110011
    -> 1101011
    

    【讨论】:

    • 这不会增加不必要的开销吗?我知道对于特定示例,这无关紧要,但作为一般最佳编程实践的问题,该算法的扩展性很差。例如,假设我们只有 20 个零,我们必须用 5 个 1 替换。该算法必须筛选factorial(20) 排列,而组合方法只需要处理更易于管理的 20 选择 5 结果。
    • 没有。解决您遇到的问题。 7 位中的哪一部分,有 4 个零没有被解决?如果您正在寻找可爱的格言,请尝试“您不需要它”
    • ... 或 “足够好就是完美”
    • 我明白你在说什么,不要误会我的意思,我不是想不尊重。只是我无法告诉你有多少次像“足够好就是完美”这样的短语不仅烧毁了我个人,而且烧毁了我的整个部门。我们花了几个月的时间来清理当时足够好的代码,而在前期对代码质量进行少量投资就可以避免这种情况。如果您实施的方法比 best 方法简单得多,我也可以理解您的观点,但实际上您的方法需要通过了解set 来增加额外的复杂性。
    • @JosephWood 嗨,对于任何明显的语气刺耳感到抱歉。因为被置换的项目有重复,所以你得到重复的烫发。对 set 的调用用于删除这些重复。 Sets 是一种原生 Python 数据结构,其接口应该比 dicts 更容易学习。至于分配哪个最好,这取决于有原始问题的人。这会计算所需的答案,显示它们,并且所有这些都在可忽略的时间和内存中。它的性能似乎足以在短时间内为 所有 可能的 7 位输入工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多