这些布尔表达式有更优雅的语法吗?

时间:2013-08-02 14:17:31

标签: c++ syntax boolean

我只是编写了递归Fibonacci算法的改进线性版本,并意识到我的布尔表达式看起来非常糟糕且难以理解。是否有清洁方式来做我想做的事情?

int fibonacci(int num) {

    if (num <= 1)
        return num;

    // starts looking ugly here

    int a = intExists(num-1);
    int b = intExists(num-2);

    bool aAndB = (a != -1 && b != -1);
    bool justA = (a != -1 && b == -1);
    bool justB = (a == -1 && b != -1);

    int number = 0;

    if (aAndB)
        number = (a + b);
    else if (justA)
        number = (a + fibonacci(num - 2));
    else if (justB)
        number = (fibonacci(num-1) + b);
    else
        number = (fibonacci(num - 1) + fibonacci(num - 2));

    map.push_back(Pair(num, number));

    return number;
}

由于

9 个答案:

答案 0 :(得分:2)

为什么不将ab设为bool,如果truea == -1则另有false。然后,表达式将变得更容易处理。

答案 1 :(得分:2)

如果你在谈论:

bool aAndB = (a != -1 && b != -1);

然后我会说,“不。”

此代码看起来非常适合我。 aAndB在它出现的那一刻被初始化,条件非常明确。当你第一次开始使用C ++时,这可能看起来有点奇怪,但在你知道它之前它将是第二天性而其他结构看起来很愚蠢。

如果您不打算更改aAndB const,我建议做一件事:

const bool aAndB = (a != -1 && b != -1);

这更具表现力。

它还可以为编译器提供额外的优化代码的机会。

记住 - 为 human 编写代码以便理解。不适合电脑理解。

答案 2 :(得分:1)

可以执行switch语句来清理if else语句。除此之外只需添加评论

答案 3 :(得分:1)

您可以将其重写为使用条件分支,如下所示:

int fibonacci(int num) {

    if (num <= 1)
        return num;

    int a = intExists(num-1);
    int b = intExists(num-2);

    const bool isA = (a != -1);   // change in the definition
    const bool isB = (b != -1);   // change in the definition

    int number = 0;

    if (isA && isB)
        number = (a + b);
    else if (isA)   // conditionnal branching
        number = (a + fibonacci(num - 2));
    else if (isB)   // conditionnal branching
        number = (fibonacci(num-1) + b);
    else
        number = (fibonacci(num - 1) + fibonacci(num - 2));

    map.push_back(Pair(num, number));

    return number;
}

答案 4 :(得分:1)

我假设intExists(n)查找map,如果在其中找到n,则返回fibonacci(n),否则返回-1。然后你可以这样做:

int fibonacci(int num) {

    if (num <= 1)
        return num;

    int a = intExists(num-1);
    int b = intExists(num-2);

    if (a == -1) // if a wasn't found, then compute it
        a = fibonacci(num-1);

    if (b == -1) // if b wasn't found, then compute it
        b = fibonacci(num-2);

    int number = a + b;
    map.push_back(std::make_pair(num, number));

    return number;
}

<强>加成:

以下是基于Binet's formula的另一个完全不同的fibonnacci()实现:

#include <cmath>

int fibonacci(int n) {
    static const double e1 =  1.6180339887498948482045868343656;  // = (1 + sqrt(5)) / 2
    static const double e2 = -0.61803398874989484820458683436564; // = (1 - sqrt(5)) / 2
    static const double c =   0.44721359549995793928183473374626; // = 1 / sqrt(5);
    double f = c * (std::pow(e1, n) - std::pow(e2, n));
    return static_cast<int>(f + 0.5);
}

int main() {
    for (int n = 1; n < 15; ++n)
        std::cout << fibonacci(n) << ' ';
}

输出:

  
    

1 1 2 3 5 8 13 21 34 55 89 144 233 377

  

答案 5 :(得分:0)

普通C ++代码足够干净:

bool a = intExists(num-1);
bool b = intExists(num-2);

if (a && b) {
  //
} else if (a) {
  //
} else if (b) {
  //
} else {
  //
}

答案 6 :(得分:0)

int a = intExists(num-1);
int b = intExists(num-2);

bool aAndB = (a != -1 && b != -1);
bool justA = (a != -1 && b == -1);
bool justB = (a == -1 && b != -1);

快速了解您采取的方法。 在什么情况下justB可以true(提示:从不)

这应该可以帮助您简化您的方法,尽管有比 memoization 更好的方法。

答案 7 :(得分:0)

更改intExists以返回布尔值,您可以执行类似的switch-case语句:

bool a = intExists(num-1);
bool b = intExists(num-2); 

switch ((a << 1) + b) {
default: // none exists
case 1: // only b exist
case 2: // only a exist
case 3: // both exists
}

理由是用二进制数转换那些布尔值

答案 8 :(得分:0)

略微激烈的重写是让外部函数处理查找表 这样,您不需要一次关注多个值。

这个使用map所以我没有必要写这么多来测试它,但它应该很容易适应:

std::map<int, int> table;

int fibonacci(int num);

int value(int num)
{
    int result = table[num];
    if (!result)
    {
        result = fibonacci(num);
        table[num] = result;
    }
    return result;
}

int fibonacci(int num) 
{
    if (num <= 2)
        return 1;
    return value(num - 1) + value(num - 2);
}