FCC 算法中级 算法和数据结构项目(五个题目)

回文检查器

如果传入的字符串是回文字符串,则返回 true。 否则返回 false

回文 palindrome,指在忽略标点符号、大小写和空格的前提下,正着读和反着读一模一样。

注意:检查回文时,你需要先去除所有非字母数字的字符(标点、空格和符号),并将所有字母都转换成大写或都转换成小写。

我们会传入具有不同格式的字符串,如 racecarRaceCar 和 race CAR 等等。

我们也会传入一些包含特殊符号的字符串,例如 2A3*3a22A3 3a22_A3*3#A2

function palindrome(str) {
  str = str.toLowerCase();
				var reg = /(?![a-z0-9])./g;
				str=str.replace(reg, '');
				for (var i = 0; i < str.length / 2; i++) {
					if (str[i] !== str[str.length-1 - i]) {
						return false;
					}
				}
				return true;
}

palindrome("eye");

(?!pattern) 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。

罗马数字转换器

把传入的数字转为罗马数字。

转换后的罗马数字字母必须都是大写。

function convertToRoman(num) {
    var ans = "";
    var k = Math.floor(num / 1000);
    var h = Math.floor((num % 1000) / 100);
    var t = Math.floor((num % 100) / 10);
    var o = num % 10;
    var one = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'];
    var ten = ['X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'];
    var hundred = ['C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM']
    var thousand = 'M';
    for (var i = 0; i < k; i++) {
        ans += thousand;
    }
    if (h)
        ans += hundred[h - 1];
    if (t)
        ans += ten[t - 1];
    if (o)
        ans += one[o - 1];
    return ans;}

convertToRoman(36);

凯撒密码

凯撒密码( Caesar cipher)是最简单且最广为人知的密码(ciphers),也被称为移位密码(shift cipher)。 在移位密码中,明文中的字母通过按照一个固定数目进行偏移后被替换成新的字母。

ROT13 是一个被广泛使用的加密技术,明文中的所有字母都被移动 13 位。 也就是, A ↔ NB ↔ O 等等。

编写一个函数,它将 ROT13 编码的字符串作为输入并返回解码字符串。

所有解码后的字母都必须为字母大写。 请不要解码非字母的字符(例如,空格、标点符号),但你需要在结果中保留它们。

function rot13(str) {
  return str.replace(/\w/g, (s) => {
        var s_code = s.charCodeAt(0);
            if (s_code <= 77) {
                return String.fromCharCode(s_code + 13);
            } else{
                return String.fromCharCode(s_code - 13);
            }
        
    });
}

rot13("SERR PBQR PNZC");

电话号码检查器

如果传入的字符串是一个有效的美国电话号码格式,则返回 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


运行测试重置所有代码

获得帮助

function telephoneCheck(str) {
 var re = /^1?\s?(\d{3}|\(\d{3}\))[ -]?\d{3}[ -]?\d{4}$/
 return re.test(str);
}


telephoneCheck("555-555-5555");

 计算找零

请编写一个用于收银机的函数 checkCashRegister():它的第一个参数为售价 price、第二个参数为支付金额 cash、第三个参数为收银机內的金额 cid

cid 是包含货币面值的二维数组。

函数 checkCashRegister() 应返回含有 status 属性和 change 属性的对象。

如果收银机內的金额少于应找回的零钱数,或者你无法返回确切的数目时,返回 {status: "INSUFFICIENT_FUNDS", change: []}

如果收银机內的金额恰好等于应找回的零钱数,返回 {status: "CLOSED", change: [...]},其中 change 的属性值就是收银机內的金额。

否则,返回 {status: "OPEN", change: [...]},其中 change 键值是应找回的零钱数,并将找零的面值由高到低排序。

货币单位 Unit面值
Penny0.01 美元(PENNY)
Nickel0.05 美元(NICKEL)
Dime0.1 美元(DIME)
Quarter0.25 美元(QUARTER)
Dollar1 美元(ONE)
Five Dollars5 美元(五)
Ten Dollars10 美元(TEN)
Twenty Dollars20 美元(TWENTY)
One-hundred Dollars100美元(ONE HUNDRED)

 下面的抽屉里现金数组示例:

[
  ["PENNY", 1.01],
  ["NICKEL", 2.05],
  ["DIME", 3.1],
  ["QUARTER", 4.25],
  ["ONE", 90],
  ["FIVE", 55],
  ["TEN", 20],
  ["TWENTY", 60],
  ["ONE HUNDRED", 100]
]

为了避免计算精度损失,采用了常用的*100再/100的方法。

 -----------------------------------

以下为解决代码

function checkCashRegister(price, cash, cid) {
    // 计算应找金额
    var change = cash * 100 - price * 100;
    // 面值数组
    var denoNum = [1, 5, 10, 25, 100, 500, 1000, 2000, 10000];
    // 面值名称数组,遍历的过程中添加
    var denoStr = [];
    // 零钱柜中可用找零总额
    var total = 0;
    // 零钱柜中面值名称与可用额度的 map
    var counterMap = {};
    // 零钱结果结果数组
    var output = [];
    //因为需要返回的是一个对象,所以创建一个对象作为返回值
    var obj = {
      status:"INSUFFICIENT_FUNDS",
      change:[]
    }

    // 遍历 cid,更新上面定义的数组,对象
    for (var i = 0; i < cid.length; i++) {
        var temp = cid[i][1] * 100;
        denoStr.push(cid[i][0]);
        counterMap[cid[i][0]] = Math.round(temp);
        total += Math.round(temp);
    }

    // 边界条件
    if (change > total) {
        return obj;
    }
    if (change === total) {
      obj.status = "CLOSED";
      obj.change = cid;
      return obj;
    }

    for (var i = denoNum.length - 1; i >= 0; i--) {
        // 找出需要试的金额,条件为比 change 小
        // 注意这里是从右开始遍历
        if (denoNum[i] <= change) {
            // 计算当前面值需要的总额
            var currentTotal = change - change % denoNum[i];

            if (counterMap[denoStr[i]] < currentTotal && counterMap[denoStr[i]] > 0) {
                // 处理柜台中当前面值的总额不为 0,但不够的情况
                output.push([denoStr[i], counterMap[denoStr[i]] / 100]);
                change -= counterMap[denoStr[i]];
            } else if (counterMap[denoStr[i]] >= currentTotal) {
                // 处理柜台中当前面值的总额够用的情况
                output.push([denoStr[i], currentTotal / 100]);
                change -= currentTotal;
            }
        }
        // 只要 change 为 0,就可以返回结果数组了
        if (change === 0) {
          obj.status = "OPEN";
          obj.change = output;
            return obj;
        }
    }
    // 执行到这里表示无法凑出应找金额
    obj.status = "INSUFFICIENT_FUNDS";
    return obj;
}
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]]);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值