仅使用递归编写C函数

时间:2016-06-13 21:18:25

标签: c algorithm recursion

我想知道数组中偶数的总和是否等于奇数之和,只使用递归而没有任何附加函数,除了递归和没有任何静态变量。

如果奇数之和等于偶数之和,则函数返回1,否则返回0.数组中的所有数字都是非负数。

函数签名应如下所示:

function(unsigned int a[], int n)

到目前为止,我写了以下内容:

function(unsigned int a[], int n)
{ 
    if(n==0) return 0;
    return (a[0]%2)?((a[0]+function(a+1,n-1)):(-a[0]+function(a+1,n-1));
}

此函数返回所需的总和,但不返回问题的答案(如果是,则为1,如果不是则为0)。

是的,这是作业的一部分,但如果没有其他不允许的功能,我无法解决。

3 个答案:

答案 0 :(得分:9)

如果我们假设计算中没有溢出:

int function (unsigned int a[], int n) {
    if (n >= 0) return !function(a, -n-1);
    if (++n == 0) return 0;
    return function(a+1, n) + ((a[0] % 2) ? -a[0] : a[0]);
}
  

在第一次调用函数时,n是非负的,并反映了数组的大小。我们递归地调用函数并在逻辑上否定结果,并且算术否定n+1。关闭一个否定允许-1表示0

在后续调用中,均衡的总和是积累的,并且赔率是负累积的。否定n会递增,直到达到0。如果总和相等,则对负n进行递归调用的结果为0,否则为非零。

返回最外层调用时,逻辑否定翻转如果总和相等则返回1,否则返回0

我会把它留作适当处理溢出的练习。

答案 1 :(得分:3)

mod @jxh nifty answer。

针对递归函数的典型抱怨是使用堆栈。对于N元素,具有N递归级别可能会耗尽递归限制。

以下代码使用log2(N)递归级别,每次调用将数组除以一半。

int function(const int a[], int n) {
  if (n > 0) return !function(a, -n);
  if (n == 0) return 0;
  if (n == -1) return (a[0] % 2) ? -a[0] : a[0];
  int half = n/2;
  int left = function(a, half);
  int right = function(&a[-half], -(-n - -half));
  return left + right;
}

答案 2 :(得分:0)

这是我的解决方案,它比你的解决方案复杂得多,而且方式也很糟糕。

int balanced(unsigned int a[], int n)
{
    if (n <= 2)
    {
        int odd = 0, even = 0;
        if (a[0]%2 == 0) even += a[0];
        else odd += a[0];
        if (a[1]%2 == 0 && n == 2) even += a[1];
        else if (n == 2) odd += a[1];
        return (odd == even);
    }

    if (a[0]%2 == 0 && a[1]%2 == 0)
    {
        a[1] += a[0];
        return balanced(a+1, n-1);
    }
    if (a[0]%2 == 0 && a[2]%2 == 0)
    {
        a[2] += a[0];
        return balanced(a+1, n-1);
    }
    if (a[1]%2 == 0 && a[2]%2 == 0)
    {
        a[2] += a[1];
        a[1] = a[0];
        return balanced(a+1, n-1);
    }
    if (a[0]%2 == 0)
    {
        if (a[0] >= a[1]+a[2])
        {
            a[0] -= (a[1]+a[2]);
            a[2] = a[0];
            return balanced(a+2,n-2);
        }
        else
        {
            a[1] = a[1]+a[2]-a[0]-1;
            a[2] = 1;
            return balanced(a+1,n-1);
        }
    }
    if (a[1]%2 == 0)
    {
        if (a[1] >= a[0]+a[2])
        {
            a[1] -= (a[0]+a[2]);
            a[2] = a[1];
            return balanced(a+2,n-2);
        }
        else
        {
            a[0] = a[0]+a[2]-a[1]-1;
            a[2] = 1;
            a[1] = a[0];
            return balanced(a+1,n-1);
        }
    }
    if (a[2]%2 == 0)
    {
        if (a[2] >= a[1]+a[0])
        {
            a[2] -= (a[1]+a[0]);
            return balanced(a+2,n-2);
        }
        else
        {
            a[1] = a[1]+a[0]-a[2]-1;
            a[0] = 1;
            a[2] = a[0];
            return balanced(a+1,n-1);
        }
    }
    else
    {
        a[2] = a[0]+a[1]+a[2];
        return balanced(a+2,n-2);
    }
}