看 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
解題想法:
- 首先令 n 等於第一位英文字母轉成的兩位數字,由於是不規則的數字結果,所以用 mapping 這個函式對應每個英文字母是比較好的做法
- 用
Math.floor(n / 10)
(n 除以十再取整數)取出 n 的第一個數字,令它為 n1 - 用取餘數的方式,取出 n 的第二個數字,令它為 n2
- 接著要求字串第二位開始與數字相乘
- 最後一位要特殊處理,並且注意型態問題
- 最後定義字串長度必須為十位;第一個字必須為大寫英文;後面的必須為數字
What I learned from it:
- Pay attention to the data type
- Math.floor()
- 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 打錯字,所以一直不會過,下次要仔細看清楚錯誤訊息提示。
明天再繼續。