簡體   English   中英

簡化遞歸函數

[英]Simplifying a Recursive Function

我有一個遞歸函數,它對整數范圍內的所有偶數求和。 我現在的代碼可以正常工作,但看起來可以簡化。 我試過把遞歸函數放在不同的地方,但每次我都得到錯誤的答案。 你們能告訴我如何縮短我的代碼嗎?

int sum_evens(int range_start, int range_end)
{
   int even_sum = 0; /* The inclusive sum of all even numbers within  */
                     /* whole number range                            */

   printf("\n   Entering sum function for range %d to %d", 
                                            range_start, range_end);
                                            
   if(range_start <= range_end)
   {
      if(is_even(range_start) == 0)
      {
         printf("\n      Adding: %d", range_start);
         even_sum = sum_evens(range_start + 1, range_end);
         even_sum += range_start;
      }
      else
      {
         printf("\n      Skipping: %d", range_start);
         even_sum = sum_evens(range_start + 1, range_end);
      } 
  }

  printf("\n   Exiting sum function for range %d to %d with result: %d",
     range_start, range_end, even_sum);
  
 return even_sum;

}

我基本上只是試圖只有這條線 (even_sum = sum_evens(range_start + 1, range_end);)

好吧,有一個數學公式可以計算這個,但如果你真的需要遞歸,你可以嘗試:

int sum_evens(int range_start, int range_end)
{
    if (range_start > range_end) return 0;
    int tmp = (is_even(range_start) == 0) ? range_start : 0;
    return tmp + sum_evens(range_start + 1, range_end);
}

但請注意,這樣的遞歸函數是“危險的”。 sum_evens(0, 2000000000)一樣調用它很可能會產生堆棧溢出。

因此,如果您不想使用數學公式,更好的方法是使用簡單的循環。

int sum_evens(int range_start, int range_end) {
    int sum = 0;
    if (is_even(range_start) != 0) ++range_start; // Make range_start even
    while(range_start <= range_end) 
    {
        sum += range_start;
        range_start += 2;
    }
    return sum;
}

順便提一句:

當數字為偶數時,您的函數is_even顯然返回 0。 這很不尋常,因為值 0 通常表示 false。 但是,在上面我保持了相同的風格。

我知道您想遞歸地執行此操作,但就像評論所說的那樣,如果您正在尋找更好更快的解決方案,您可以使用簡單的迭代或實際的算術公式,據說

#include <stdio.h>

int sum_evens(int range_start, int range_end) {
    printf("Entering sum function for range %d to %d\n",
           range_start, range_end);

    if (range_start > range_end) return 0;
    int val = range_start % 2 == 0 ? range_start : 0;
    return val + sum_evens(range_start + 1, range_end);
}

int main() {
    int val = sum_evens(1, 10);
    printf("\n%d", val);
    return 0;
}

這里可以使用三元運算符,而不是使用 if else 語句將值添加到總和,然后再次調用該函數以啟動遞歸

如果要使用 void 函數和指針

#include <stdio.h>

void sum_evens(int range_start, int range_end, int * initiator) {

    printf("Entering sum function for range %d to %d\n", range_start, range_end);

    if (range_start <= range_end) {
        int val = range_start % 2 == 0 ? range_start : 0;
        (*initiator) += val;
        sum_evens(range_start + 1, range_end, initiator);
    }
}

int main() {
    int sum = 0;
    sum_evens(1, 3, &sum);
    printf("\n%d", sum);
    return 0;
}

使用迭代(for 循環)

#include <stdio.h>

int sum_evens(int range_start, int range_end) {
    int sum = 0;
    for (int i = range_start; i <= range_end; i++) 
        if (i % 2 == 0) sum += i;
    return sum;
}

int main() {
    int val = sum_evens(1, 10);
    printf("\n%d", val);
    return 0;
}

沒什么可添加的,但首先要養成編寫基本條件的習慣,以便減少它分配的執行時間和空間,因為在這里您的函數也上升到 n+1,這也是不必要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM