D19_開始第三週


Posted by Christy on 2021-05-07

看 ALG101 Unit5

Unit5.2:實戰:判斷等差數列

題目:
判斷陣列是否為等差數列,是則回傳 true,否回傳 false;陣列為空或只有一位回傳 true

Judge if an array is an arithmetic sequence or not; if yes return true or return false. When an array is empty or only has one digit, return true

我的第一個想法是下面的程式碼:
Here's the version one:

function Ari(arr) {
    if (arr.length <= 1) {
        return true
    }
    let tolerance = arr[1] - arr[0]
    for (let i=1; i<arr.length; i++) {
        if (arr[i] - arr[i-1] === tolerance) {
            return true
        }
    }
    return false  
}

然後我發現這個程式碼有一個邏輯瑕疵,就是迴圈從 1 開始跑,那我迴圈裡面的判斷式一定會成立,接著就回傳 true 整個迴圈就結束了。

就算是我把 i 設成 2 開始跑,那這個函式也無法正確地判斷這個陣列 [1, 2, 3, 4, 9]

I found there's a logic problem with the version one, cuz my for loop starts from one and it must equal arr[i] - arr[i-1] === d, and then return true

If I set i =2, I can't judge an array like this [1, 2, 3, 4, 9]

所以最好的方法就是寫成這樣:
so the best way is like this:

function Ari(arr) {
    if (arr.length <= 1) {
        return true
    }
    let tolerance = arr[1] - arr[0]
    for (let i=1; i<arr.length; i++) {
        if (arr[i] - arr[i-1] !==tolerance) {
            return  false
        }
    }
    return true
}

console.log(Ari([])) //true
console.log(Ari([1]))//true
console.log(Ari([1, 2, 3, 4, 5]))//true
console.log(Ari([1, 2, 3, 9]))//false
console.log(Ari([20, 32, 40]))//false

Unit5.3:實戰:身分證驗證

題目:驗證台灣的身份證字號,編碼規則

判斷台灣身份證號碼
規則:第一位為英文字母,後九位為數字
英文字母會被轉成兩位數字,所以共十一位(參考以下表格)
把每一個數字依序乘上1、9、8、7、6、5、4、3、2、1、1,最後再相加
相加結果除以十,若是整除則有效

A 10, B 11, C 12, D 13, E 14, F 15,
G 16, H 17, I 34, J 18, K 19, L 20,
M 21, N 22, O 35, P 23, Q 24, R 25,
S 26, T 27, U 28, V 29, W 32, X 30,
Y 31, Z 33

I am glad there's only 26 alphabets...😂

Verify Taiwanese ID number, reference

function validTWID(str) {
    if (str.length !== 10) return false
    //這裡就忽略蔣先生的九碼身分證
    if (!(str[0] >= 'A' && str[0] <= 'Z')) return false
    //檢查是否第一位是否為大寫數字
    for (let a = 1; a<=str.length -1; a++) {
        if (!(str[a] >= 0 && str[a] <= 9)) {
            return false
        }
    }
    //檢查第二位到第十位是否為數字

    let n = alphaToNumber(str[0])
    let n1 = Math.floor(n / 10)
    let n2 = n % 10

    let sum = n1 * 1 + n2 * 9
    // let sum = str[1] * 8 + str[2] * 7 + ... str[8] * 1 + str[9] * 1
    for (i=1; i<str.length - 1; i++) {
        sum += str[i] * (9-i) //乘法不用轉成數字
    }
    sum += Number(str[9]) //注意型態問題,取字串的某一位,出來會是字串

    if (sum % 10 === 0) {
        return true
    } else return false

}

function alphaToNumber(s) {
    let mapping = {
        A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, G: 16, H: 17, I: 34,
        J: 18, K: 19, L: 20, M: 21, N: 22, O: 35, P: 23, Q: 24, R: 25,
        S: 26, T: 27, U: 28, V: 29, W: 32, X: 30, Y: 31, Z: 33 
    }
    return mapping[s]
}

// 用上面的 mapping 版面比較簡潔
// function alphaToNumber(s) {
//     if (s === 'A') return 10
//     if (s === 'B') return 11
//     if (s === 'C') return 12
//     if (s === 'D') return 13
//     if (s === 'E') return 14
//     if (s === 'F') return 15
//     if (s === 'G') return 16
//     if (s === 'H') return 17
//     if (s === 'I') return 34
//     if (s === 'J') return 18
//     if (s === 'K') return 19
//     if (s === 'L') return 20
//     if (s === 'M') return 21
//     if (s === 'N') return 22
//     if (s === 'O') return 35
//     if (s === 'P') return 23
//     if (s === 'Q') return 24
//     if (s === 'R') return 25
//     if (s === 'S') return 26
//     if (s === 'T') return 27
//     if (s === 'U') return 28
//     if (s === 'V') return 29
//     if (s === 'W') return 32
//     if (s === 'X') return 30
//     if (s === 'Y') return 31
//     if (s === 'Z') return 33
// }

console.log(validTWID('A123456789')) //true
console.log(validTWID('a299')) //false
console.log(validTWID('A123456788')) //false
console.log(validTWID('P12345sdff')) //false
  • 解題想法:

    1. 首先令 n 等於第一位英文字母轉成的兩位數字,由於是不規則的數字結果,所以用 mapping 這個函式對應每個英文字母是比較好的做法
    2. Math.floor(n / 10) (n 除以十再取整數)取出 n 的第一個數字,令它為 n1
    3. 用取餘數的方式,取出 n 的第二個數字,令它為 n2
    4. 接著要求字串第二位開始與數字相乘
    5. 最後一位要特殊處理,並且注意型態問題
    6. 最後定義字串長度必須為十位;第一個字必須為大寫英文;後面的必須為數字
  • What I learned from it:

    1. Pay attention to the data type
    2. Math.floor()
    3. mapping
  • 我在重做一次的過程中,發覺我一點也不了解物件的特色,我的問題在於「要怎麼輸入 key 取得 value?」,嘗試了半小時,找到這篇文章
    答案就是用 mapping.A,結果就會輸出 value 10

但是我覺得也許現階段我不需要知道這麼詳細吧?

let mapping = {
    A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, G: 16, H: 17, I: 34,
    J: 18, K: 19, L: 20, M: 21, N: 22, O: 35, P: 23, Q: 24, R: 25,
    S: 26, T: 27, U: 28, V: 29, W: 32, X: 30, Y: 31, Z: 33 
}

console.log(mapping.A)
//就會輸出 10

我在重寫的過程中發現了其實我也可以把

i<str.length - 1 (也可以寫成 9,因為是跑到第九個元素)
 for (i=1; i<=9; i++) {
        sum += str[i] * (9-i)
    }

然後在測試的過程中發現我 mapping 打錯字,所以一直不會過,下次要仔細看清楚錯誤訊息提示。
明天再繼續。










Related Posts

滲透測試基本技術 第一章

滲透測試基本技術 第一章

React Elements

React Elements

JS this / 原型鏈 學習筆記

JS this / 原型鏈 學習筆記


Comments