freeCodeCamp —- JavaScript Algorithms and Data Structures
JavaScript算法和数据结构项目
1. 回文检查器 如果传入的字符串是回文字符串,则返回 true
。 否则返回 false
回文 palindrome,指在忽略标点符号、大小写和空格的前提下,正着读和反着读一模一样。
注意 :检查回文时,你需要先去除所有非字母数字的字符 (标点、空格和符号),并将所有字母都转换成大写或都转换成小写。
我们会传入具有不同格式的字符串,如 racecar
、RaceCar
和 race CAR
等等。
我们也会传入一些包含特殊符号的字符串,例如 2A3*3a2
、2A3 3a2
、2_A3*3#A2
。
1 2 3 4 5 6 7 8 9 10 11 12 13 function palindrome (str ) { let newStr = str.split (/[\W_]+/gi ).join ('' ).toLowerCase (); let len = newStr.length ; console .log (newStr) for (let i =0 ;i < len; i++ ){ if ( newStr[i] != newStr[len - i - 1 ]){ return false ; } } return true ; } palindrome ("A man, a plan, a canal. Panama" );
2. 罗马数字转换器 把传入的数字转为罗马数字。
罗马数字
阿拉伯数字
M
1000
CM
900
D
500
CD
400
C
100
XC
90
L
50
XL
40
X
10
IX
9
V
5
IV
4
I
1
所有罗马数字答案都应该大写。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 function convertToRoman (num ) { var romanNumerals = [ {value :1000 , letter :'M' }, {value :900 , letter :'CM' }, {value :500 , letter :'D' }, {value :400 , letter :'CD' }, {value :100 , letter :'C' }, {value :90 , letter :'XC' }, {value :50 , letter :'L' }, {value :40 , letter :'XL' }, {value :10 , letter :'X' }, {value :9 , letter :'IX' }, {value :5 , letter :'V' }, {value :4 , letter :'IV' }, {value :1 , letter :'I' } ]; var romanNumeral = '' ; for (var i = 0 ; i < romanNumerals.length ; i++) { while (num >= romanNumerals[i].value ) { romanNumeral += romanNumerals[i].letter ; num -= romanNumerals[i].value ; } } return romanNumeral; } console .log (convertToRoman (1234 ));
3. 恺撒密码 恺撒密码( Caesar cipher)是最简单且最广为人知的密码(ciphers),也被称为移位密码(shift cipher)。 在移位密码中,明文中的字母通过按照一个固定数目进行偏移后被替换成新的字母。
现代最常被应用到的一个变种就是 ROT13 加密,也就是明文中的字母向后移 13 位。 也就是, A ↔ N
,B ↔ O
等等。
编写一个函数,它将把使用 ROT13 加密编码的字符串作为输入并返回解码字符串。
所有解码后的字母都必须为字母大写。 请不要解码非字母的字符(例如,空格、标点符号),但你需要在结果中保留它们。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function rot13 (str ) { let output = '' ; for (let i = 0 ;i<str.length ;i++){ let charCode =str.charCodeAt (i); if (charCode>=65 &&charCode<=90 ){ output += String .fromCharCode ((charCode -65 + 13 ) % 26 +65 ); }else { output += str.charAt (i) } } return output } rot13 ("SERR PBQR PNZC" );
4. 电话号码检查器 如果传入的字符串是一个有效的美国电话号码格式,则返回 true
。
只要是有效的美国电话号码的格式,用户可以按照他们的方式填写表单中的电话号码。 以下是一些正确的例子(其他格式变形请参考以下例子):
555-555-5555 (555)555-5555 (555) 555-5555 555 555 5555 5555555555 1 555 555 5555
在这个挑战中,参数可能是 800-692-7753
或者 8oo-six427676;laskdjf
的号码。 你的任务是根据上面不同的格式组合,判断它是否为有效的电话号码。 其中,地区码(电话号码中的前三位)是必须的。 如果提供国家代码,则国家代码只能为 1
。 如果传入的参数是有效的美国电话号码就返回 true
,否则返回 false
。
1 2 3 4 5 6 7 8 9 10 11 12 13 function telephoneCheck (str ) { let regex = /^(1\s?)?(\(\d{3}\)|\d{3})([\-\.\s])?\d{3}([\-\.\s])?\d{4}$/ ; return regex.test (str); } telephoneCheck ("555-555-5555" );
5. 计算找零 请编写一个用于收银机的函数 checkCashRegister()
:它的第一个参数为售价 price
、第二个参数为支付金额 cash
、第三个参数为收银机內的金额 cid
。
cid
是包含货币面值的二维数组。
函数 checkCashRegister()
应返回含有 status
属性和 change
属性的对象。
如果收银机內的金额少于应找回的零钱数,或者你无法返回确切的数目时,返回 {status: "INSUFFICIENT_FUNDS", change: []}
。
如果收银机內的金额恰好等于应找回的零钱数,返回 {status: "CLOSED", change: [...]}
,其中 change
的属性值就是收银机內的金额。
否则,返回 {status: "OPEN", change: [...]}
,其中 change
键值是应找回的零钱数,并将找零的面值由高到低排序。
货币单位 Unit
面值
Penny
0.01 美元(PENNY)
Nickel
0.05 美元(NICKEL)
Dime
0.1 美元(DIME)
Quarter
0.25 美元(QUARTER)
Dollar
1 美元(ONE)
Five Dollars
5 美元(五)
Ten Dollars
10 美元(TEN)
Twenty Dollars
20 美元(TWENTY)
One-hundred Dollars
100美元(ONE HUNDRED)
下面的抽屉里现金数组示例:
1 2 3 4 5 6 7 8 9 10 11 [ ["PENNY" , 1.01 ], ["NICKEL" , 2.05 ], ["DIME" , 3.1 ], ["QUARTER" , 4.25 ], ["ONE" , 90 ], ["FIVE" , 55 ], ["TEN" , 20 ], ["TWENTY" , 60 ], ["ONE HUNDRED" , 100 ] ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 function checkCashRegister (price, cash, cid ) { const currencyUnits = [ { name : "ONE HUNDRED" , value : 100.00 }, { name : "TWENTY" , value : 20.00 }, { name : "TEN" , value : 10.00 }, { name : "FIVE" , value : 5.00 }, { name : "ONE" , value : 1.00 }, { name : "QUARTER" , value : 0.25 }, { name : "DIME" , value : 0.10 }, { name : "NICKEL" , value : 0.05 }, { name : "PENNY" , value : 0.01 } ]; let changeDue = cash - price; let cashAvailable = cid.reduce ((total, current ) => total + current[1 ], 0 ); let change = []; if (changeDue > cashAvailable) { return { status : "INSUFFICIENT_FUNDS" , change : [] }; } else if (changeDue.toFixed (2 ) === cashAvailable.toFixed (2 )) { return { status : "CLOSED" , change : cid }; } else { cid = cid.reverse (); for (let i = 0 ; i < currencyUnits.length ; i++) { let currencyAmount = 0 ; while (changeDue >= currencyUnits[i].value && cid[i][1 ] >= currencyUnits[i].value ) { currencyAmount += currencyUnits[i].value ; cid[i][1 ] -= currencyUnits[i].value ; changeDue -= currencyUnits[i].value ; changeDue = Math .round (changeDue * 100 ) / 100 ; } if (currencyAmount > 0 ) { change.push ([currencyUnits[i].name , currencyAmount]); } } if (changeDue > 0 ) { return { status : "INSUFFICIENT_FUNDS" , change : [] }; } return { status : "OPEN" , change : change }; } } checkCashRegister (19.5 , 20 , [["PENNY" , 1.01 ], ["NICKEL" , 2.05 ], ["DIME" , 3.1 ], ["QUARTER" , 4.25 ], ["ONE" , 90 ], ["FIVE" , 55 ], ["TEN" , 20 ], ["TWENTY" , 60 ], ["ONE HUNDRED" , 100 ]]);