簡體   English   中英

Eloquent JavaScript 2nd Edition 遞歸練習解決方案

[英]Eloquent JavaScript 2nd Edition recursion exercise solution

我試圖解決在線書籍eloquentjavascript 2nd edition的遞歸練習:

以下是問題的內容:

我們已經看到 %(余數運算符)可用於通過使用 %2 來檢查數字是否可被 2 整除來測試數字是偶數還是奇數。 這是定義(正數,整數)數是偶數還是奇數的另一種方法:

  • 零是偶數。
  • 一個是奇葩。
  • 對於任何其他數字 N,其偶數與 N - 2 相同。

定義一個遞歸函數 isEven 對應於這個描述。 該函數應該接受一個數字參數並返回一個布爾值。

在 50 和 75 上測試它。看看它在 -1 上的表現。 為什么? 你能想辦法解決這個問題嗎?

這是我嘗試過的並且有效:

function isEven(number) {
    if (number == 0) {
        return true;
    } else {
        return (-number % 2 == 0) ? true : false;
    }
    return isEven(number - 2);
}

console.log(isEven(-1));

但是,這似乎是一個錯誤的答案,因為據我了解,作者希望我使用 - 2 方法。 我想知道這是否確實是正確的答案,或者如果它是錯誤的,有人可以指出我正確的方向。

我認為您感到困惑的原因是因為您不了解遞歸的工作原理。 它是 n-2 的原因是,它正在取數字並減去 2,直到它是零或一。 因此給我們一個真假。

希望有幫助。 閱讀遞歸過程的工作原理。

下面提供了不使用模運算符%或任何其他 JavaScript 內置函數的替代解決方案。 這個解決方案依賴於使用另一個遞歸來改變數字的負值。

function isEven(number) {
    if (number < 0) {
        return isEven(-number);
    } else if (number == 1) {
        return false;
    } else if  (number == 0) {
        return true;
    } else {
        return isEven(number - 2);
    }
}

console.log(isEven(50)); // true
console.log(isEven(75)); // false
console.log(isEven(-1)); // false

我們調用 isEven(number -2) 返回函數的頂部,輸入的數字比之前少 2,它會一直這樣做,直到數字為 1 或 0,然后它將能夠返回布爾值 true 或 false(偶數或奇數)。

我認為問題是在不使用 mod/%/remainder 操作的情況下創建一個 isEven 函數

function isEven(number) {
  if (number < 0) {
    number = Math.abs(number);
  }
  if (number===0) {
    return true;
  }
  if (number===1) {
    return false;
  }
  else {
    number = number - 2;
    return isEven(number);
  }

}

我想補充一點很重要

  1. 它不處理字符串
  2. 它不處理浮動
  3. 不要把它放到生產應用程序中
function isEven(n) {
 n = Math.abs(n);
  if (n==0) 
    return true;
  else if (n==1)
    return false;
  else 
    return isEven(n-2);
}

console.log(isEven(-50)); // → true
console.log(isEven(75)); // → false
console.log(isEven(-75)); // → false
console.log(isEven(-1)); // → false
var isEven = function(n) {
  // Get the absolute value of the number
  // so we don't have to bother with negatives
  n = Math.abs(n);

  // We know that if we subtract 2 from our number
  // until it is equal to zero, our number was even
  // If our number isn't zero, this statement will be skipped
  if(n === 0) return true;

  // We know that if we subtract 2 from our number
  // and it reaches a value of 1, it isn't even
  // If our number isn't 1, this statement will be skipped
  if(n === 1) return false;

  // We subtract 2 from our original number and pass it
  // back in to this function to check it over and over again
  // until one of the conditions is met and the function can
  // return a result
  return isEven(n - 2);
}

// We test our function here
console.log(isEven(-21));

這是我能想到的最精簡的方法。 請注意,我們從自身內部調用 isEven 函數並傳入 n - 2 的值。這將不斷從我們的數字中減去 2 並檢查它是否等於 0 或 1,直到我們得到正確的結果並返回相應的布爾值.

我希望這能讓事情變得清晰一點。

下面的代碼怎么樣? 似乎對我有用。

/*if > 1 keep looking, otherwise return reverse boolean value. 
If negative value, inverse, to answer the last part of the question... 
Also needed to use parseInt as the text value I used, 
was considered a string value!
This being a recursive function which really isn't necessary, 
means that in javascript we will get a 
stack size exceeded error when the number becomes too large.*/

function isEven(x) {
    return (x>1)?isEven(x-2):(x>=0)?!x:isEven(-x);
}

這本書希望這些值的以下 console.log 輸出

console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-2));
// → ??

提示說“當給定一個負數時,該函數將一次又一次地遞歸,傳遞給自己一個越來越多的負數,從而越來越遠離返回結果。它最終會耗盡堆棧空間並中止。” 所以我不確定我得到的是否代表,但我的代碼和 console.log 輸出如下所示:

   let isEven = function(num) {
         if (num ===0) {
             return true
         } else if (num===1){
             return false
         } else {
             return isEven(num-2)
         }
    }    

console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-2));
// → RangeError: Maximum call stack size exceeded (line 3 in function isEven)```

問題要求您不要使用模運算符 (%)。

// Your code here.
var isEven = function(a){
  if (a == 0){ //case 1 : zero is even
    return true;
  }
  else if(a == 1){ //case 2: one is odd 
    return false;
  }
    else {
      return isEven(Math.abs(a-2)); //solves case 3 (negative numbers)
    }
}

console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-1));
// → ?? ....false

這是網站上的“正確”答案。 我用引號說“正確”,因為我不明白第二個 'else if' 語句的return isEven(-n) 為什么作者包含將n變成正數的選項?

function isEven(n) {
  if (n == 0)
    return true;
  else if (n == 1)
    return false;
  else if (n < 0)
    return isEven(-n);
  else
    return isEven(n - 2);
}

無論如何,我想我會分享,因為我沒有看到有人發布這個答案。

//define recursive function isEven takes a positive whole number
//returns true if even
function isEven(x) {
  //define innner function to loop over value
  function find(current) {
    //check if value == 0, return true
    if (current == 0) { 
      return true
    //check if value == 1 return false
     } else if (current == 1)  {
        return false
    //loop over value, subtracting 2 each time until either 0 or 1
    //which returns the approriate true/false value based on evenness
     } else {
     console.log(current)
     return find(current -2)
    }
  }
    return find(x)
}

如果數字是1-1所以ODD ,函數返回false
如果數字是0所以EVEN ,它返回true

如果那么 number 或 1,-1 或 0 我們必須首先檢查數字是正數還是負數,

如果數字為小於 -1,我們再次調用該函數,將數字增加 2,直到得到 -1 或 0;
如果數字為大於 1,我們再次調用該函數,將數字減少 2,直到得到 1 或 0;

例如,數字是5 ->
它是正數且大於 1,因此一遍又一遍地調用該函數並將數字減 2,直到結果為 0 或 1:
5->3->1 //->假

    function isEven(num) {
    if (num == 1 || num == -1) {
        return false;
    } else if (num == 0) {
        return true;
    } else {
        if (num < -1) {
            return isEven(num + 2);
        } else {
            return isEven(num - 2);
        }
    }
}

測試結果:

console.log(`-35 is even: ${isEven(-35)}`); //-> false
console.log(`-1 is even: ${isEven(-1)}`);  //-> false
console.log(`0 is even: ${isEven(0)}`);  //-> true
console.log(`32 is even: ${isEven(32)}`);  //-> true

我在上面看到了很多使用數學函數和模運算符的例子。 但我猜作者期望一個簡單的遞歸函數讓讀者理解它的功能,以及如果沒有正確定義它是如何導致重復的函數調用並最終導致堆棧溢出的。 我相信下面的這段代碼可以幫助你理解:

 function isEven(n){ if(n==0){ return true; } else if(n==1){ return false; } else { return isEven(n-2); } } console.log(isEven(50)); console.log(isEven(75)); console.log(isEven(-1));

function isEven(num){
 if(num %2 == 0) {
 return true;
} else {
  return false;
 }
}

console.log(isEven(50));
// → true

console.log(isEven(75));
// → false

console.log(isEven(-1));
// → ??

希望更好地理解遞歸,我想知道這個解決方案是否有效。

function isEven(n) {
    function checkNumber(num){
        if ( num % 2 === 0)
            return true;
        else
            return false;
        }
    return checkNumber(-n); // instead of return isEven(n - 2) where stack blows
}

console.log(isEven(50)); // -> true

console.log(isEven(75)); // -> false


console.log(isEven(-1)); // -> false

console.log(isEven(-2)); // -> true
function isEven(number) {
    while(number>= -1)
    {   
        return isEven(number-2) == 0 && number>-1 ? true : false;
    }
}
console.log(isEven(-1));

我希望這有幫助:

const evenOrOdd = (N) => {
    if (Math.abs(N) === 0) {
        return console.log('Even');
    } else if (Math.abs(N) === 1) {
        return console.log('Odd');
    }
    evenOrOdd(Math.abs(N) - 2);
};

谷歌瀏覽器控制台代碼結果:

它在問題上使用了所有三個給定的論點。 它可以處理負整數。 它不使用模運算符。 最后,我無法看到任何類似於我提供的代碼片段,因此我很想分享我能做的。

暫無
暫無

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

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