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

bitwise function to compare any possible option combination

我有以下枚举:

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);
}

是的,但不是那样的。观察 option 的值,你就会明白为什么 - 一旦你将两个子查询放在一起,一切都会出错。

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

如果您使用和积形式,您的查询将类似于 (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;
}

对于产品总和表,您的查询看起来像 (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;
}