Javascript算法练习(八)

来源:互联网 发布:阿里云 手机归属地 编辑:程序博客网 时间:2024/05/16 18:55

Javascript算法练习(八)

updateInventory,更新库存,即用新的数组数据去更新老的数组数据

  • 思路:遍历新数组中的数据

    • 更新老数据:根据名称去老数组中查找,找到了就用对应的数量与老的相加;
    • 添加新数据:如果没找就将新数组中的数据添加到老数组中;
    /** * 11. 用第二个数组的数据去更新第一个数组数据(更新库存) * @param  {Array} oldArr 原始数据 * @param  {Array} newArr 新数据 * @return {Array}        返回更新后的老数据数组并且根据名称排序后的二维数组 * * PS: 1. 两个数组都是二维数组 *     2. 两个数组的内容要一致即元素的第一个元素为数量,第二个元素为名称, *         比如:oldArr = [[22, "hello"]], newArr = [[33, "hello"]];  更新后就是:[[55, "hello"]] */ArrayHandler.prototype.updateInventory = function (oldArr, newArr) {    if (!oldArr || !newArr) return;    var compare = function (a, b) {        var ua = a[1].toUpperCase();        var ub = b[1].toUpperCase();        if (ua < ub) {            return -1;        }        if (ua > ub) {            return 1;        }        if (ua == ub) {            return 0;        }    };    if (oldArr.length === 0) return newArr.sort(compare);    if (newArr.length === 0) return oldArr.sort(compare);    var findFlag = 0; // 找到存在的库存标识    newArr.map(function (newValue) {        oldArr.map(function (oldValue) {            if (oldValue[1] == newValue[1]) {                oldValue[0] += newValue[0]; // 同类产品库存数累加                findFlag = 1;                return;            }        });        // 到这里表示没有库存,直接添加        if (!findFlag) {            oldArr.push(newValue);  // 新产品直接添加        }        // 复位库存标识        findFlag = 0;    });    // 排序    oldArr.sort(compare);    return oldArr;}

checkCashRegister:模拟收银抽屉,给出购买的物品价格及所付金额,算出找零

  • 思路:

    • 先定义好金钱面值(这个与国家相对应,每个国家的面值不同,并且基本上不会有所改变,此例以美元为准),这里需要注意,将所有面值按一美元为单位乘以基数(如:100),避免用浮点数去操作避免因精度问题,最后得到的值不正确;
    • 然后用所付款金额减去购物需付款得到找零金额,最后去面值数组中,从高到底的去取值;
    • 通过对找零金额取余和取除数,得到相应面值金额所需要找出的张数;
    /** * 9. 模拟收银抽屉,给出购买的物品价格及所付金额,算出找零 * @param  {Number} price 商品价格 * @param  {Number} cash  所付金额 * @param  {Array} cid   剩余金额的二维数组 * @return {Array}       返回需要找零的金额的二维数组,里面包含了找零对应的面值 * * 最后一个参数cid,即面值剩余金额数组,必须要和国家钱币对应的面值金额相一致,且顺序从小到大排 * 例如:[  *         // 对应1美分(Cent)、5美分(Nickel)、10美分(Dime,一角)、25美分(Quarter)、 *         // 1美元(ONE)、5美元(FIVE)、10美元(TEN)、20美元(TWENTY)、100美元(ONE HUNDRED) *         ["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25],  *         ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00] *       ] * * TODO:最后可以将dollar数组,当成参数传进去,与cid数组的内容顺序要一致,分别表示钱币金额面值数, *     根据基数base和国家钱币面值不同,数组会不相同 */NumberHandler.prototype.checkCashRegister = function (price, cash, cid) {    // 刚刚好    if (price == cash) return "No Need Back";    // 付款不足    if (price > cash) return "Need More Money";    var base        = 100;      // 金额基数    var change      = (cash - price) * base; // 找零    var getTotalMoney = function (arr) {        var totalMoney = 0;        arr.reduce(function (preV, currV, currIndex, array){            totalMoney += base * (preV[1] + currV[1]);            return currV;        });        return totalMoney;    }    // 余额不足,没法找了    var remain = getTotalMoney(cid);    if (remain == change) { // 零钱刚好找完了        return "Closed";        } else if (remain < change) { // 没钱找了        return "Insufficient Funds - 1";    }    // 分别对应,1美分-5美分-1角-25美分-1美元-5美元-10美元-20美元-100美元    // 这里还可以进行优化,让dollar成为参数,而动态获取相应国家的金额面值    // 比如代表中国的:[10, 50, 100, 500, 1000, 2000, 5000, 10000] ->     // 对应:1角-5角-1元-5元-10元-20元-50元-100元(以元为单位的基础上乘以面值基数:base这里为100)    var dollar      = [1, 5, 10, 25, 100, 500, 1000, 2000, 10000]; // TODO    var pay         = {};   // 保存的key:dollar中面值索引,value:要找的此面值的个数    var currLast    = 0;    // 当前面值所剩余额    var currMoney   = 0;    // 当前金钱面额(dollar中对应的值)    for (var i = dollar.length - 1; i >= 0; i--) {        // 当前面值剩余金额        currLast = cid[i][1] * base;        // 当前面值的金额剩余0,跳过        if (currLast <= 0) {             continue;        }        // 当前金额面值        currMoney = dollar[i];        // 达到找零的面值必须满足两个条件:        // 1. 找零必须大于当前面值        // 2. 剩余的当前面值的钱足够的情况下        if (change > currMoney) {            if (change < currLast) {                 // 找零小于当前面值剩余金额                pay[i + ""] = parseInt(change / currMoney);                change -= currMoney * pay[i + ""];            } else {                // 找零大于当前面值剩余金额,则将所有剩余金额找出                pay[i + ""] = parseInt(currLast / currMoney);                change -= currLast; // 就直接减去当前面值剩余所有金额            }        }    }    var res = [];    // 组织最后需要找零的钱    var keys = Object.keys(pay);    var idx = 0;    for (var j = 0; j < keys.length; j++) {        // 需要找零的面值索引        idx = parseInt([keys[j]]);        // 该面值最后找出的零钱(公式:面值 * 需要找出数量 / 金钱面值基数)        cid[idx][1] = dollar[idx] * pay[keys[j]] / base;        console.log("-------- " + cid[idx][1]);        res.unshift(cid[idx]);        // total += dollar[idx] * pay[keys[j]]; // 这里计算的结果应该和最开始需要找零的金额一致    }     // 找到最后,所有能找的面值加起来还不够    // 这里与最开始不同,这里是过滤掉了所有找不开的面值    // 比如:要找0.05元,但是目前剩余一张0.01和1元的面值,依旧判定为找不开    // 而最开始的是所有余额加起来都不够找    if (getTotalMoney(res) < change) {        return "Insufficient Funds - 2";    }    return res;}

getPermutation:获取字符串的所有排列结果,返回所有结果组成的字符串数组

  • 思路:这里主要还是考察到递归的使用,还是有点不太明白,虽然整出结果来了,还需好好深入递归去研究研究下

    /** * 5. 获得指定字符串的所有排列结果的数组 * @return {[type]} [description] */StringHandler.prototype.getPermutation = function () {    var resArr      = [];    return function perm(str, start) {        var permArr     = str.split("");        var end         = permArr.length;        for (var j = start; j < end; j++) {            // 交换数组中两个索引位置的值            swap(permArr, j, start);            // 保存交换后的字符串,如果曾经保存过则过滤掉,避免重复            var tmpStr = permArr.join("");            if (resArr.indexOf(tmpStr) == -1) {                resArr.push(tmpStr);            }            // 重置交换起始位置,递归直到最后一位字符结束,即:start > end            perm(tmpStr, start + 1, end);        }        return resArr;    };}();

总结

最近有点松懈了,加上组里现在整个模块的业务都让我一个人搞,老大跑去做维护新系统去了,所以最近也很忙(借口总是很多,呸………..!!!),还是要加紧学习,打好基础,不能松懈了。今天整了这三个练习,记录下,还算有点收获吧。给自己打打气,加油吧!!!

0 0
原创粉丝点击