C - 数组中最小间隙的递归函数

时间:2017-01-26 23:52:58

标签: c recursion optimization

我试图优化一个函数,给定一个N int 数组,返回一个元素和 previous <之间的最小差异/ strong>一个。显然,该函数仅适用于维度> = 2的数组。 例如,给定数组{2,5,1},函数返回-4。 我试着写我的代码,但我认为它真的是错综复杂的

#include <stdio.h>
#define N 4
/*Function for the difference, works because in the main I already gives one difference*/
int minimodiff(int *a, int n, int diff) {
  if (n==1) {
    return diff;
  }
  if (diff>(*(a+1) - *a))
     return minimodiff(a+1, n-1, *(a+1)-*a);
  else return minimodiff(a+1, n-1, diff);
}

int main() {
  int a[N]= {1,8,4,3};
  printf("%d", minimodiff(a+1, N-1, *(a+1)-*a));
}

我想知道是否有办法避免传递 main 中的第一个区别,但是在递归函数中执行所有操作。 我可以使用头文件stdio.h / stdlib.h / string.h / math.h。非常感谢您的帮助,我希望这可以让我对递归函数有更好的理解

3 个答案:

答案 0 :(得分:4)

minimodiff(a+1, N-1, *(a+1)-*a)是一种使用递归的弱方法,因为它使用N的递归深度,这很容易超过系统资源的深度限制。在这种情况下,简单的循环就足够了。

一个好的递归方法会在每次调用时将问题减半,找到左半部分和右半部分的最小值。它可能运行得不快,但最大递归深度为log2(N)

// n is the number of array elements 
int minimodiff2(const int *a, size_t n) {
  if (n == 2) {
    return a[1] - a[0]; 
  } else if (n <= 1) {
    return INT_MAX;
  }
  int left = minimodiff2(a, n/2 + 1);  // +1 to include a[n/2] in both halves
  int right = minimodiff2(a + n/2, n - n/2);
  return (left < right) ? left : right;
}

int main() {
  int a[]= {1,8,4,3};
  printf("%d", minimodiff2(a, sizeof a/ sizeof a[0]));
}

答案 1 :(得分:2)

当进行最小计算,递归或其他时,如果将min设置为最高可能值,则会使初始条件更简单。如果您使用浮点数,则为Infinity。由于您使用的是整数,因此INT_MAX from limits.h被定义为可能的最大整数。它保证大于或等于所有其他整数。

如果您使用循环迭代地执行此操作,则最初设置diff = INT_MAX。由于这是递归,INT_MAX是递归完成时返回的内容。

#include <limits.h>

static inline int min( const int a, const int b ) {
    return a < b ? a : b;
}

int minimodiff( const int *a, const size_t size ) {
    if( size <= 1 ) {
        return INT_MAX;
    }

    int diff = a[1] - a[0];
    return min( minimodiff(a+1, size-1), diff );
}

答案 2 :(得分:1)

递归方法是一个坏主意,因为使用了额外的内存和函数调用 无论如何,你的问题是避免第一个区别 你可以使用中心 由于参数diff是一个int变量,因此无法获得大于INT_MAX的值 因此,您可以通过将值INT_MAX作为与diff相对应的参数来完成对minimodiff的第一次调用 此外,标准头限制必须在顶部#include,以使INT_MAX宏可见。