簡體   English   中英

遞歸javascript函數不起作用

[英]Recursive javascript function is not working

我正在嘗試遞歸。

我只希望輸出是輸入乘以2的結果: output = 2*input

應該是這樣,為什么不起作用?

function fE(f) {
  if(f < 0){
    return 1;}
  else{
  return f + fE(f);}


}

console.log(fE(3)); // output 6
console.log(fE(6)); // 12

遞歸涉及一個基本情況,在您的情況下為零輸入。 在這種情況下,答案為零。 否則,將問題減少為2的總和,並以較少的參數遞歸調用函數的結果。 如果輸入為負,則返回輸入求反結果的求反。

 function fE(f) { if (f === 0) return 0; else if (f < 0) return -fE(-f); else return 2 + fE(f - 1); } console.log(fE(3)); // output 6 console.log(fE(6)); // 12 console.log(fE(-4)); // -8 

您的代碼:

function fE(f) {
  if(f < 0){
    return 1;}
  else{
  return f + fE(f);}
}

有以下問題:

  1. 如果輸入為零或更少,則可能要返回零,而不是一。
  2. 否則,您希望遞歸的值比輸入小一。 fE(f)將導致無限循環,對不對?
  3. 您不想將f添加到遞歸結果中; 您想添加2,這是獲得雙倍效果的地方。

如圖所示,您的函數將嘗試無限遞歸,因為具有f + fE(f)的行上的遞歸調用每次都傳遞相同的f值,這意味着第一行的if測試將始終失敗。

遞歸地實現它沒有任何意義,因為您可以用一行代碼來計算正確的結果:

function fE(f) { return 2 * f; }

遞歸函數的一個更好的例子(出於學習目的)可能是通過大量遞歸調用將任意兩個數相乘的函數:

multiply(10, 3)  // return 30

...同樣可以輕松地在一行中實現:

function multiply(a, b) { return a * b; }

...但是您可以像這樣遞歸地做到這一點:

 function multiply(a, b) { console.log(a, b); if (b === 0) return 0; else if (b === 1) return a; else if (b < 0) return -multiply(a, -b); else return a + multiply(a, b-1); } multiply(12, 4) // 48 multiply(5, -3) // -15 multiply(3, 0) // 0 

請注意,每次函數調用自身時,它都會在第二個參數中傳遞一個不同的值,以便最終else if (b === 1)條件為true,並且遞歸將停止。 我包含了console.log(a,b)以便您可以自己查看每個調用的參數。

@torazaburo和@nnnnnn的很好答案–它們很實用,應該可以解決您的直接問題。 我將提供其他替代方法,希望這些方法可以幫助您的大腦以多種方式思考遞歸過程。

另一種常見的遞歸技術是在輔助函數中使用狀態變量

 function mult (x, y) { function aux (result, counter) { if (counter === 0) return result else return aux (result + x, counter - 1) } return aux (0, y) } console.log(mult (5, 4)) // 20 

這是另一種使用延續傳遞樣式的技術

 function multk (x, y, k) { if (y === 0) k (0) else multk (x, y - 1, function (result) { k (result + x) }) } multk (5, 4, function (result) { console.log(result) /* 20 */ }) 

這是一個堅果式的簡化版本,僅使用原始+1和原始-1 它看起來似乎很復雜,但是我為您構建了它,以便您可以了解如何用較小的遞歸程序構建更復雜的遞歸程序。 如果您可以遵循此代碼,它將有助於您更好地理解遞歸。

(我添加了一些console.log行,以便您可以更好地直觀了解正在發生的事情。您不想將它們留在代碼中。)

 function add1 (x) { return x + 1 } function sub1 (x) { return x - 1 } function add (x, y) { console.log('adding:', x, y) if (y === 0) return x else return add (add1(x), sub1(y)) } function mult (x, y) { function aux (result, counter) { console.log('multiplying:', result, counter) if (counter === 0) return result else return aux (add(result, x), sub1(counter)) } return aux (0, y) } console.log('result:', mult (5, 4)) // 20 

和同樣的事情使用無限分隔的延續

 function add1 (x, k) { k (x + 1) } function sub1 (x, k) { k (x - 1) } function addk (x, y, k) { console.log('adding:', x, y) if (y === 0) k (x) else add1 (x, function (x1) { sub1 (y, function (y1) { addk (x1, y1, k) }) }) } function multk (x, y, k) { function aux (result, counter, k) { console.log('multiplying:', result, counter) if (counter === 0) k (result) else addk (result, x, function (result1) { sub1 (counter, function (counter1) { aux (result1, counter1, k) }) }) } aux (0, y, k) } multk (5, 4, function (result) { console.log('result:', result) /* 20 */ }) 

暫無
暫無

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

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