<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一道算法小題的分析過程

          共 3671字,需瀏覽 8分鐘

           ·

          2021-03-02 12:57

          關(guān)注 ▲前端思維框架 和眾多前端精英,一起向上生長

          后臺回復電子書獲取為你整理的2021年前端書單


          作者:水墨寒







          理解題目


          最近在看算法的問題比較多,希望能以一道小題,來記錄算法分析的過程。題目是: Pig Latin


          Pig Latin is a way of altering English Words. The rules are as follows:

          • If a word begins with a consonant, take the first consonant or consonant cluster, move it to the end of the word, and add “ay” to it.

          If a word begins with a vowel, just add “way” at the end.

          遇到這種描述比較少的題,第一反應是題目描述越簡單,隱藏條件就會多。不慌先看維基百科 對于 Pig Latin 的解釋: 豬拉丁 。我喜歡在看題目的時候,先看看維基百科,會了解下題目的背景和淵源,讓自己更好的理解題目的同時,讓解題也有些趣味性。簡單解析下規(guī)則:當一個單詞以輔音字母開頭,將輔音字母移到最后,并添加 ay 比如

          • california → aliforniacay : c 移動到最后然后添加 ay

          • paragraphs → aragraphspayp 移動到最后然后添加 ay

          • glove → oveglaygl 移動到最后然后添加 ay ?? 這里是找到第一個元音字母之前的所有輔音字母

          元音字母: a、e、i、o、u

          當單詞以元音字母開頭的時候直接在單詞后面添加way 比如

          • algorithm → algorithmway : a 是元音字母所以在單詞后添加 way

          • eight → eightway : e 是元音字母所以在單詞后添加 way

          題目分析完了,我們還需要通過閱讀測試用例來檢查是否有遺漏,看最后一條:

          Should handle words without vowels. translatePigLatin(“rhythm”) should return “rhythmay”.

          這個規(guī)則其實滿足第一種情況,當找不到元音的時候,直接在后面加 ay







          分析過程


          當我們拿到一道算法題目的時候,按照幾個套路來「攻城」

          1. 算法分類,這道題是字符串題,對于字符串的操作無非有兩種:

            1. 按索引遍歷

            2. replace,replace 中尤其以正則不講武德。

          2. 由淺入深:

            1. 就是上來先根據(jù)給出的條件,按照暴力的方向去寫偽代碼

            2. 在根據(jù)邏輯找關(guān)鍵循環(huán)因子 和 優(yōu)化手段

            3. 嘗試優(yōu)化









          偽代碼


          先寫偽代碼,這部分代碼比較糙,主要用于整理分析過程

          VAR STR 
          VAR vowelLetters = ['a','e','i','o','u']
          // 以元音開頭
          IF STR[0] in vowelLetters
          return STR + 'way'
          // 在STR中找到元音索引
          FOR (S, INDEX) in STR
          IF S IN vowelLetters
          return STR.slice(INDEX) + STR.slice(0,INDEX) + 'ay'
          // 單詞中沒有元音
          renturn STR + ay
          復制代碼

          分析過程有了我們可以寫JavaScript代碼了

          function translatePigLatin(str) {
          // 先準備需要的元音數(shù)組
          const vowelLetters = ['a','e','i','o','u']
          // 特殊情況:如果以元音開頭
          if(vowelLetters.includes(str[0])) return `${str}way`

          // 正常情況
          for (let i = 0; i < str.length; i++) {
          if(vowelLetters.includes(str[i])) {
          return `${str.slice(i)}${str.slice(0, i)}ay`
          }
          }

          // 如果前面攔不住 說明沒有元音
          return `${str}ay`
          }

          translatePigLatin("consonant");
          復制代碼

          Review 上面??代碼,已經(jīng)可以通過測試了,那么分析如何優(yōu)化 。從代碼中分析到整個核心的邏輯就落在 ${str.slice(i)}${str.slice(0, i)}ay 那么關(guān)鍵點在于找到 第一個元音的索引那么我們改代碼

          function translatePigLatin(str) {
          // 直接找索引
          let index = str.split('').findIndex(s => /[aeiou]/.test(s))

          if(index < 0)return `${str}ay`
          if (index === 0)return `${str}way`
          return `${str.slice(index)}${str.slice(0, index)}ay`
          }

          translatePigLatin("consonant");
          復制代碼

          代碼簡化一些,邏輯更清晰了







          另一條路


          從分析過程的路上來看,已經(jīng)用循環(huán)遍歷的方法完成了,那么另一條路(replace)應該如何實現(xiàn)?第一種方法的結(jié)果來看,需要用到正則分組的方法來調(diào)換位置。思路是分兩組第一組是開頭到元音,第二組是元音到結(jié)尾。然后將這兩組順序調(diào)換后,添加后綴。在開發(fā)和調(diào)試正則的時候,推薦 regex101.com/ 來調(diào)試正則表達式

          通過調(diào)試器來完成這個正則:/([^aeiou]*)(\w*)/ 解釋下

          1. 用兩個括號,分成兩組

          2. ([^aeiou]*) 表示匹配不是(^)aeiou 的0到多個字符。

          3. (\w*) 剩下字符是一組

          完成代碼

          function translatePigLatin(str) {
          return str.replace(/([^aeiou]*)(\w*)/, '$2$1ay')
          }

          translatePigLatin("consonant");
          復制代碼

          通過測試,??上面的代碼已經(jīng),除了元音在開頭的情況沒有覆蓋,其他兩種情況是包含的。元音在開頭的時候,需要加的后綴為way, 也就是當 ([^aeiou]*) 匹配的不到的 $1 為空的時,后綴變成 ay 順著這個思路完善,JavaScript 字符串 replace 方法第二個參數(shù)是支持函數(shù)的 String.prototype.replace() - JavaScript | MDN

          function translatePigLatin(str) {
          return str.replace(/([^aeiou]*)(\w*)/, (_, p1, p2) => `${p2}${p1||'w'}ay`)
          }

          translatePigLatin("consonant");
          復制代碼









          總結(jié)


          總結(jié)下 當拿到一道算法題的基本套路是

          1. 分類,是那一類的題,分完類后基本上能確定方向,比如樹的題大部分都要用到遞歸,如果你想刻意訓練遞歸,可以在樹分組下訓練。

          2. 先分析題目邏輯,先用簡單粗暴的方法把邏輯的偽代碼寫出來,然后再突破優(yōu)化。

          3. Review 其他方向上是否有更優(yōu)解。



          最后給個小建議:如果你是短期想突破面試,刷leetcode。同時推薦:https://www.codewars.com/,相比之下codewars 更注重當前編程語言的實操,而不是以最優(yōu)算法為目的,里邊有很多「意外驚喜」。會被很多「奇技淫巧|黑暗魔法」所折服。據(jù)坊間流傳 codewars 的難度上限更高。

          end


          如果您喜歡“前端思維框架”的文章,請設“置頂”哦。點擊最上方藍色字體“前端思維框架”→點擊右上角“...”→點選“設為星標??”。


          “星標”公眾號查看方法:在微信對話框里點擊“訂閱號消息”→點擊右上角“三”,即可快速找到“前端思維框架”。

          瀏覽 49
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  高清无码爱爱视频 | 欧美自拍视频在线观看? | 清清清草视频 | 拍黄色毛片电影视频 | www.青青操 |