按位函数来比较任何可能的选项组合

时间:2015-01-19 12:57:03

标签: bit-manipulation bitwise-operators

我有以下枚举:

typedef enum _options {          
    o1=1,
    o2=2,
    o3=4,
    o4=8
} option;

是否可以使用一个函数来检查它们的任何组合,例如(逻辑上说):

o1 OR o2 OR o3

o1 AND o2

o1 AND (o2 OR o3)

(o1 OR o2) AND (o3 OR o4)

option=(o1|o2|o3)的以下工作,但不适用于option=((o1|o2) & (o3|o4))

BOOL doesMyValueHaveOption(option o) { 
    int v = myValue;
    return (v & o);
}

1 个答案:

答案 0 :(得分:1)

是的,但不是那样的。观察option的值,看看为什么 - 只要你和两个子查询一起出现,一切都会出错。

对于任意查询,您需要至少一个选项列表(每个选项也是一个组合),可以是产品总数或产品总和形式。这意味着您必须将查询(实际上是表达式树)转换为其中一种形式,这可能会导致指数爆炸。但是,它可能仍然是一种合理的方法,具体取决于典型查询的结构。如果它真的必须是通用的,你最好把它作为树传递(或者也许是DAG,你也可以共享相同的子树)。

如果你选择Sums产品表单,你的查询看起来像(o1 OR o2 OR o4) AND (o2 OR o3 OR o5) AND (etc..,你就会传递一个列表{o1 | o2 | o4, o2 | o3 | o5, etc }并将其实现为(未经测试)

BOOL doesMyValueHaveAllOptions(vector<option> options) { 
    int v = myValue;
    for (auto o : options)
        if (!(v & o))
            return false;
    return true;
}

对于Sum Of Products表单,您的查询看起来像(o1 AND o3 AND o4) OR (o2 AND o4 AND o5) OR etc..,您会传递一个列表{o1 | o3 | o4, o2 | o4 | o5, etc}注意,当o在查询中通过“AND”连接时,它们会被合并在列表中使用OR(因为否则它只是零),您可以将其实现为(未测试)

// todo: make up a better name
BOOL doesMyValueHaveAtLeastOneCombinationOfOptions(vector<option> options) { 
    int v = myValue;
    for (auto o : options)
        if ((v & o) != o)
            return false;
    return true;
}