第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何通過迭代方法編寫遞歸函數(shù)?

如何通過迭代方法編寫遞歸函數(shù)?

繁星點點滴滴 2023-07-29 10:51:36
我如何在使用遞歸時編寫下面相同的代碼,我用迭代方法完成了它,如果有人可以幫助我使用遞歸進(jìn)行編碼,我將非常感激!這是我的代碼:function returnNumberOfPalindromes(word) {  function checkForPalindrome(chunk) {     let chunkArray = [];    for (const letter of chunk) {       chunkArray.push(letter);    }    if (chunkArray.reverse().join('') === chunk) {      tally += 1;    }  }  let tally = 0;  for (let index1 = 0, index2 = 2; index1 <= word.length; index1++, (index2 = index1 + 2)) {    for (; index2 <= word.length; index2++) {       let chunk = word.slice(index1, index2);       checkForPalindrome(chunk);    }  }  console.log(tally);}returnNumberOfPalindromes("kayak");returnNumberOfPalindromes("aya");returnNumberOfPalindromes("appal");returnNumberOfPalindromes("addadaadd");
查看完整描述

2 回答

?
largeQ

TA貢獻(xiàn)2039條經(jīng)驗 獲得超8個贊

一系列的重構(gòu)

經(jīng)過一系列的重構(gòu),我們最終將得到以下代碼:


const isPalindrome = (s) =>  

  s.length == 0 ? true : s[0] === s[s.length - 1] && isPalindrome(s.slice(1, -1))


const countPalindromicPrefixes = (s) =>

  s.length < 2 ? 0 : (isPalindrome(s) ? 1 : 0) + countPalindromicPrefixes(s.slice (0, -1)) 


const countPalindromes = (s) => 

  s.length < 2 ? 0 : countPalindromicPrefixes(s) + countPalindromes(s.slice(1))



console .log (countPalindromes ("kayak"));

console .log (countPalindromes ("aya"));

console .log (countPalindromes ("appal"));

console .log (countPalindromes ("addadaadd"));

console .log (countPalindromes ("madamimadam"));


每個步驟都有一個片段(默認(rèn)情況下隱藏,因此不會太長),顯示到目前為止我們還沒有破壞任何內(nèi)容。


初始點

初始代碼如下所示:


function returnNumberOfPalindromes(word) {

  function checkForPalindrome(chunk) { 

    let chunkArray = [];

    for (const letter of chunk) { 

      chunkArray.push(letter);

    }

    if (chunkArray.reverse().join('') === chunk) {

      tally += 1;

    }

  }

  let tally = 0;


  for (let index1 = 0, index2 = 2; index1 <= word.length; index1++, (index2 = index1 + 2)) {

    for (; index2 <= word.length; index2++) { 

      let chunk = word.slice(index1, index2); 

      checkForPalindrome(chunk);

    }

  }

  console.log(tally);

}

function returnNumberOfPalindromes(word) {

  function checkForPalindrome(chunk) { 

    let chunkArray = [];

    for (const letter of chunk) { 

      chunkArray.push(letter);

    }

    if (chunkArray.reverse().join('') === chunk) {

      tally += 1;

    }

  }

  let tally = 0;


  for (let index1 = 0, index2 = 2; index1 <= word.length; index1++, (index2 = index1 + 2)) {

    for (; index2 <= word.length; index2++) { 

      let chunk = word.slice(index1, index2); 

      checkForPalindrome(chunk);

    }

  }

  console.log(tally);

}


returnNumberOfPalindromes("kayak");

returnNumberOfPalindromes("aya");

returnNumberOfPalindromes("appal");

returnNumberOfPalindromes("addadaadd");

修復(fù)for循環(huán)

作為外部循環(huán)增量的一部分更新內(nèi)部循環(huán)的初始索引有一些非常奇怪的事情。這是更常見的,而且我敢說,更符合邏輯:


  for (let index1 = 0; index1 <= word.length; index1++) {

    for (let index2 = index1 + 2; index2 <= word.length; index2++) { 

      let chunk = word.slice(index1, index2); 

      checkForPalindrome(chunk);

    }

  }

function returnNumberOfPalindromes(word) {

  function checkForPalindrome (chunk) { 

    if (chunk.split('').reverse().join('') === chunk) {

      tally += 1;

    }

  }

  let tally = 0;


  for (let index1 = 0; index1 <= word.length; index1++) {

    for (let index2 = index1 + 2; index2 <= word.length; index2++) { 

      let chunk = word.slice(index1, index2); 

      checkForPalindrome(chunk);

    }

  }

  console.log(tally);

}


returnNumberOfPalindromes("kayak");

returnNumberOfPalindromes("aya");

returnNumberOfPalindromes("appal");

returnNumberOfPalindromes("addadaadd");

returnNumberOfPalindromes("madamimadam");

簡化checkForPalindrome

正在進(jìn)行的大部分工作checkForPalindrome都是不必要的。 String.prototype.split已經(jīng)將字符串轉(zhuǎn)換為字符數(shù)組。所以我們可以將該部分更改為:


  function checkForPalindrome (chunk) { 

    if (chunk.split('').reverse().join('') === chunk) {

      tally += 1;

    }

  }

function returnNumberOfPalindromes(word) {

  function checkForPalindrome (chunk) { 

    if (chunk.split('').reverse().join('') === chunk) {

      tally += 1;

    }

  }

  let tally = 0;


  for (let index1 = 0; index1 <= word.length; index1++) {

    for (let index2 = index1 + 2; index2 <= word.length; index2++) { 

      let chunk = word.slice(index1, index2); 

      checkForPalindrome(chunk);

    }

  }

  console.log(tally);

}


returnNumberOfPalindromes("kayak");

returnNumberOfPalindromes("aya");

returnNumberOfPalindromes("appal");

returnNumberOfPalindromes("addadaadd");

returnNumberOfPalindromes("madamimadam");

使局部函數(shù)成為純函數(shù)

我們的內(nèi)部函數(shù)checkForPalindrome沒有返回值。相反,它正在更新 的狀態(tài)tally。這使得它更難理解。讓我們將其更改為checkForPalindromereturntrue或false,并tally根據(jù)該結(jié)果進(jìn)行更新:


  function checkForPalindrome (chunk) { 

    return chunk.split('').reverse().join('') === chunk

  }

      if (checkForPalindrome(chunk)) {

        tally += 1

      }

function returnNumberOfPalindromes(word) {


  function checkForPalindrome (chunk) { 

    return chunk.split('').reverse().join('') === chunk

  }


  let tally = 0;


  for (let index1 = 0; index1 <= word.length; index1++) {

    for (let index2 = index1 + 2; index2 <= word.length; index2++) { 

      let chunk = word.slice(index1, index2); 

      if (checkForPalindrome(chunk)) {

        tally += 1

      }

    }

  }

  console.log(tally);

}


returnNumberOfPalindromes("kayak");

returnNumberOfPalindromes("aya");

returnNumberOfPalindromes("appal");

returnNumberOfPalindromes("addadaadd");

returnNumberOfPalindromes("madamimadam");

取出內(nèi)部函數(shù)

仍然關(guān)注checkForPalindrome,我們可以注意到它現(xiàn)在是一個有用的函數(shù)來確定字符串是否是回文。因此,我們不妨將其從我們的主要功能中取出并使其獨(dú)立。


true但返回or的函數(shù)的常見約定false是將其命名為以is. 在這種情況下,isPalindrome肯定更有意義。所以我們改成這樣:


function isPalindrome (word) { 

  return word.split('').reverse().join('') === word

}


      if (isPalindrome(chunk)) {

        tally += 1

      }

function isPalindrome (word) { 

  return word.split('').reverse().join('') === word

}


function returnNumberOfPalindromes(word) {


  let tally = 0;


  for (let index1 = 0; index1 <= word.length; index1++) {

    for (let index2 = index1 + 2; index2 <= word.length; index2++) { 

      let chunk = word.slice(index1, index2); 

      if (isPalindrome(chunk)) {

        tally += 1

      }

    }

  }

  return tally;

}


console .log (returnNumberOfPalindromes("addadaadd"));  //=> 7

把這個遞歸

現(xiàn)在邁出一大步。我們想讓這個遞歸。讓我們檢查一下主循環(huán)正在做什么:


  for (let index1 = 0; index1 <= word.length; index1++) {

    for (let index2 = index1 + 2; index2 <= word.length; index2++) { 

      let chunk = word.slice(index1, index2); 

      if (isPalindrome(chunk)) {

        tally += 1

      }

    }

  }

此代碼在索引中循環(huán)兩次,查找從索引 0 開始的所有子字符串,然后從索引 1 開始查找所有子字符串,然后從索引 2 開始查找所有子字符串,依此類推。對于每個子字符串,它都會測試字符串是否為回文,以及是否為回文。 ,我們增加計數(shù)。


這種雙循環(huán)幾乎肯定意味著我們也會進(jìn)行雙遞歸。所以我們可以認(rèn)為它有兩個功能。


一個函數(shù)接受一個字符串并查看該字符串的所有前綴(例如,對于“goat”,前綴將為“goat”、“goa”、“go”和“g”)并計算那些前綴的數(shù)量。是回文。如果單詞長度少于兩個字符,則它沒有回文,我們返回0,否則我們包含1該單詞是否是回文,0如果不是,則將其添加到刪除最后一個字符的遞歸調(diào)用的結(jié)果中:


function returnNumberOfPalindromicPrefixes(word) {

  if (word .length < 2) {

    return 0

  }

  return (isPalindrome(word) ? 1 : 0) + returnNumberOfPalindromicPrefixes(word.slice(0, -1)) 

}

第二個函數(shù)在字符串的開頭重復(fù)出現(xiàn)。同樣,如果單詞長度少于兩個字符,我們再次返回0。否則,我們將調(diào)用前綴函數(shù)的結(jié)果添加到對刪除第一個字符形成的字符串的遞歸調(diào)用中:


function returnNumberOfPalindromes(word) {

  if (word .length < 2) {

    return 0

  }

  return returnNumberOfPalindromicPrefixes(word) + returnNumberOfPalindromes(word.slice(1))

}

function isPalindrome(word) { 

  return word.split('').reverse().join('') === word

}


function returnNumberOfPalindromicPrefixes(word) {

  if (word .length < 2) {

    return 0

  }

  return (isPalindrome(word) ? 1 : 0) + returnNumberOfPalindromicPrefixes(word.slice(0, -1)) 

}


function returnNumberOfPalindromes(word) {

  if (word .length < 2) {

    return 0

  }

  return returnNumberOfPalindromicPrefixes(word) + returnNumberOfPalindromes(word.slice(1))

}


console .log (returnNumberOfPalindromes("kayak"));

console .log (returnNumberOfPalindromes("aya"));

console .log (returnNumberOfPalindromes("appal"));

console .log (returnNumberOfPalindromes("addadaadd"));

console .log (returnNumberOfPalindromes("madamimadam"));

插曲

至此我們就有了合理的代碼。我們將其重構(gòu)為邏輯相當(dāng)清晰且相當(dāng)清晰的遞歸函數(shù)。(這也與 Applet123 的答案非常相似。)

這對您(或您的教練)來說可能已經(jīng)足夠了。

但我認(rèn)為還有更多有用的改變需要做出。將接下來的幾個步驟視為錦上添花。

函數(shù)命名

這聽起來可能微不足道,但名字returnNumberOf<Whatever>卻相當(dāng)可怕。count<Whatever>可能numberOf<Whatever>會好得多sizeOf<Whatever>。

我將選擇第一個,它將為我們提供名稱countPalindromicPrefixescountPalindromes

function isPalindrome (word) { 

  return word.split('').reverse().join('') === word

}


function countPalindromicPrefixes(word) {

  if (word .length < 2) {

    return 0

  }

  return (isPalindrome(word) ? 1 : 0) + countPalindromicPrefixes(word.slice(0, -1)) 

}


function countPalindromes(word) {

  if (word .length < 2) {

    return 0

  }

  return countPalindromicPrefixes(word) + countPalindromes(word.slice(1))

}


console .log (countPalindromes("kayak"));

console .log (countPalindromes("aya"));

console .log (countPalindromes("appal"));

console .log (countPalindromes("addadaadd"));

console .log (countPalindromes("madamimadam"));

更現(xiàn)代的 JS

使用箭頭函數(shù)而不是函數(shù)聲明可以清理大量代碼。 條件(三元)運(yùn)算符也可以。使用這些我們可以變成這樣:


function countPalindromes(word) {

  if (word .length < 2) {

    return 0

  }

  return countPalindromicPrefixes(word) + countPalindromes(word.slice(1))

}

進(jìn)入這個:


const countPalindromes = (word) => 

  word .length < 2 ? 0 : countPalindromicPrefixes(word) + countPalindromes(word.slice(1))

并對其他功能執(zhí)行類似的操作。

const isPalindrome = (word) =>  

  word.split('').reverse().join('') === word


const countPalindromicPrefixes = (word) =>

  word.length < 2 ? 0 : (isPalindrome(word) ? 1 : 0) + countPalindromicPrefixes(word.slice(0, -1)) 


const countPalindromes = (word) => 

  word.length < 2 ? 0 : countPalindromicPrefixes(word) + countPalindromes(word.slice(1))



console .log (countPalindromes ("kayak"));

console .log (countPalindromes ("aya"));

console .log (countPalindromes ("appal"));

console .log (countPalindromes ("addadaadd"));

console .log (countPalindromes ("madamimadam"));

參數(shù)命名

我們在這里為我們的函數(shù)使用參數(shù)名稱“word”。但我們真的想讓這成為一個詞嗎?這句話“一個人,一個計劃,一條運(yùn)河:巴拿馬!” 被廣泛描述為回文。(雖然它不適合我們的測試,但我們可以通過在執(zhí)行當(dāng)前測試之前降低值并刪除任何非字母字符來輕松修復(fù)它。)事實上,我向其中添加了一個測試用例,它捕獲另一個經(jīng)典回文的版本“女士,我是亞當(dāng)”。


那么輸入可以是一個單詞或一個句子?也許也是一個短語?人們有時會談?wù)摂?shù)字是回文數(shù),例如 2112。因此“單詞”并不是這些數(shù)字的正確名稱。我們的似乎采用任意字符串。因此,我們應(yīng)該將參數(shù)重命名為捕獲該參數(shù)的名稱。也許是“str”?也許是“字符串”?我將提出一些更激進(jìn)的建議。我們確實不知道類型,而且它是一個單行函數(shù),因此仍然具有“字符串”風(fēng)格的單字符名稱在這里似乎完全合理。我會選擇“s”。請注意,有些人厭惡這種想法。這可能包括你的教練,所以要小心。(如果有人反對,你可以隨時向他們推薦一篇關(guān)于這個想法的文章,描述性變量名稱:代碼味道,約翰·德戈斯著。但他們可能仍然開始向你扔?xùn)|西,所以要小心。)


所以我們可以這樣寫:


const countPalindromicPrefixes = (s) =>

  s.length < 2 ? 0 : (isPalindrome(s) ? 1 : 0) + countPalindromicPrefixes(s.slice(0, -1)) 

const isPalindrome = (s) =>  

  s.split('').reverse ().join('') === s


const countPalindromicPrefixes = (s) =>

  s.length < 2 ? 0 : (isPalindrome(s) ? 1 : 0) + countPalindromicPrefixes(s.slice(0, -1)) 


const countPalindromes = (s) => 

  s.length < 2 ? 0 : countPalindromicPrefixes(s) + countPalindromes(s .slice(1))



console .log (countPalindromes ("kayak"));

console .log (countPalindromes ("aya"));

console .log (countPalindromes ("appal"));

console .log (countPalindromes ("addadaadd"));

console .log (countPalindromes ("madamimadam"));

遞歸地做所有的事情

除了課堂作業(yè)之外,我不會做以下事情。我們已經(jīng)有了 的一個工作版本isPalindrome,一個可讀且高效的版本。但由于這顯然是一個遞歸分配,因此編寫一個遞歸版本可能會很好isPalindrome。

為此,我們可以遞歸地考慮這個問題,注意如果第一個和最后一個字符匹配并且中間的字符串也是回文,則字符串是回文。空字符串在這里被視為回文,單字符字符串也是如此。(在這種情況下,第一個和最后一個字符指向同一個地方,所以它們當(dāng)然是相同的。)我們可以這樣寫:

const isPalindrome = (s) =>  
  s.length == 0 ? true : s[0] === s[s.length - 1] && isPalindrome(s.slice(1, -1))

請注意,對于這里的一般問題,我們沒有將 1 字符子字符串視為回文,但這是在主函數(shù)中處理的。 isPalindrome很高興地這樣報告它們,這似乎很合適。

const isPalindrome = (s) =>  

  s.length == 0 ? true : s[0] === s[s.length - 1] && isPalindrome(s.slice(1, -1))


const countPalindromicPrefixes = (s) =>

  s.length < 2 ? 0 : (isPalindrome(s) ? 1 : 0) + countPalindromicPrefixes(s.slice (0, -1)) 


const countPalindromes = (s) => 

  s.length < 2 ? 0 : countPalindromicPrefixes(s) + countPalindromes(s.slice(1))



console .log (countPalindromes ("kayak"));

console .log (countPalindromes ("aya"));

console .log (countPalindromes ("appal"));

console .log (countPalindromes ("addadaadd"));

console .log (countPalindromes ("madamimadam"));


查看完整回答
反對 回復(fù) 2023-07-29
?
函數(shù)式編程

TA貢獻(xiàn)1807條經(jīng)驗 獲得超9個贊

我不會checkForPalindrome遞歸地編寫,因為這樣做很簡單:


function checkForPalindrome(str) {

  // we can use .split("") to convert to an array of characters

  return str.split("").reverse().join("") == str;

}


function palindromesAtStart(str) {

  // lengths 0 and 1 can't be palindromes

  if (str.length < 2) {

    return 0;

  }

  // if it's a palindrome add 1

  const diff = checkForPalindrome(str) ? 1 : 0;

  // now shorten the string and check again

  return diff + palindromesAtStart(str.slice(0, -1));

}


function returnNumberOfPalindromes(str) {

  if (str.length < 2) {

    return 0;

  }

  // total palindromes is palindromes at start plus palindromes not at start

  return palindromesAtStart(str) + returnNumberOfPalindromes(str.slice(1));

}



console.log(returnNumberOfPalindromes("kayak"));

console.log(returnNumberOfPalindromes("aya"));

console.log(returnNumberOfPalindromes("appal"));

console.log(returnNumberOfPalindromes("addadaadd"));


本質(zhì)上,字符串中的回文可以包含第一個索引,也可以不包含第一個索引。因此,我們可以編寫一個簡單的遞歸函數(shù)(palindromesAtStart)來計算包含第一個索引的回文數(shù),并將其添加到不包含第一個索引的回文數(shù)中。


查看完整回答
反對 回復(fù) 2023-07-29
  • 2 回答
  • 0 關(guān)注
  • 154 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號