【问题标题】:Change Cash Function Optimization - Javascript更改现金功能优化 - Javascript
【发布时间】:2018-08-01 13:15:22
【问题描述】:

今天我来帮助你优化一些代码!

几周前,我被要求在测试中解决一个问题,因为我开始学习 Javascript,所以我想出了这个非最佳解决方案。

我想知道是否有办法(当然有)让这变得更好。

情况如下:

“我是一个特别善良的人,拥有无限量的 2 美元、5 美元和 10 美元的钞票,我愿意为任何想要它的人兑换现金,但以最有效的方式,用最少的账单。”

由于我必须返回一个带有钞票数量的对象(如果小于 2 美元,则返回 null),我给出了以下解决方案:

function giveChange(change){    
var two = 0;
var five = 0;
var ten = 0;
var changeToGo = change;

while(changeToGo >= 11){
    changeToGo -=10;
    ten+=1;
}

while(changeToGo >=7 && changeToGo <=11){
    changeToGo-=5;
    five+=1;
}

while(changeToGo >=2 && changeToGo <=6 ){
    if(changeToGo == 5){
        changeToGo -=5;
        five+=1;
}
    else{
        changeToGo -= 2;
        two+=1;
    }
}

if (change < 2){
    return null;
}

return {
    two: two,
    five: five,
    ten: ten
};
}

我认为必须有一个聪明和更优雅的解决方案(可能使用 mod% 或其他东西),但那个怪物是我当时能够实现的哈哈哈。

有什么想法吗?

【问题讨论】:

  • 对不起,我不得不重写函数,因为我记得在飞行中,该函数在测试版本上工作,这只是一个错字。 (现在正在编辑)。
  • 大多数开发人员可能会使用模数运算符。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 好吧。最佳(和一般)解决方案与分区有关,这是一个难题。在接下来的几天里,我将尝试提供一个优雅的解决方案。这条评论让我记住
  • 我们如何在这种情况下使用模数?另外,我问的是效率,因为在非常大的数字中,我最终使用了很多内存,而这在测试中是不允许的,我不得不做一个非常丑陋的技巧来解决这个问题。

标签: javascript function oop object


【解决方案1】:

编辑:删除了他最初的答案,因为它是基于对要求的误解。

好的,那么让我们扭转局面,首先让我们确定我需要分发多少张 2 美元的钞票才能得到一个可以被 5 美元钞票整除的数字。所以现在我只关心剩余的

一般的想法是,如果我有一个 change%5 为 2 的值,例如 12 美元或 17 美元或 22 美元,...我分发一张 2 美元的钞票,我可以将其余部分除以 5。

对于像 14 美元、19 美元……这样的价值,是两张 2 美元的钞票,11 美元、16 美元……我减去 6 美元,13 美元、18 美元……就是 8 美元

这样我就有了一张静态表格,其中列出了每张change % 5 需要分发多少张 2 美元的钞票;不需要任何循环,只需简单的查找即可。

function giveChange(change){
  const two = change < 4? change>>1: [0,3,1,4,2][Math.floor(change) % 5],
    rest = change - two*2;

  return { 
    two,
    five: Math.floor((rest%10)/5), 
    ten: Math.floor(rest/10), 
  };
}

想再次解释一下这是做什么的? "更改>>1" 和 "[0,3,1,4,2][Math.floor(change) % 5];" ?

change &gt;&gt; 1 在这里只是Math.floor(change/2) 的简写,主要处理giveChange(1) 和giveChange(3) 的特殊情况;它们不可互换,但对于0..4(我使用它的地方)范围,它们会产生相同的结果。

let two = [0,3,1,4,2][change % 5];

//does 
let two;
if(change%5 === 0) two = 0;
if(change%5 === 1) two = 3;
if(change%5 === 2) two = 1;
if(change%5 === 3) two = 4;
if(change%5 === 4) two = 2;

而Math.floor(change) % 5 是为了以防万一您将其与浮点数一起使用,例如giveChange(25.90)

但也许一个例子可以更好地解释它

for(let change=4; change<50; ++change){
  let two = [0,3,1,4,2][change%5];
  console.log("change: %i, two: %i, rest: %i", change, two, change - two*2);
}
.as-console-wrapper{top:0;max-height:100%!important}

您会看到two 总是以相同的顺序具有相同的 5 个值,以及现在其余的值如何被 5 或 10 整除。

这就是这段代码的作用,它查找数组[0,3,1,4,2],对于任何给定的change,它需要使用多少张2美元的钞票,所以剩下的可以被5整除。

【讨论】:

  • 使用 floor 方法,我们最终会遇到抢客户 1 美元的问题。
  • @Platiplus 是的,但是值
  • 如果你尝试单独更改$1,它们会被忽略,因为那是不可能的,但如果你可以通过更改其他账单来达到结果,它们就不能被忽略。
  • @Platiplus,添加了第二个代码来解决这个问题;没有循环左右。加上解释
  • 老兄,这太疯狂了!想再次解释一下这是做什么的? "更改>>1" 和 "[0,3,1,4,2][Math.floor(change) % 5];" ?记住我是一个真正的初学者。
【解决方案2】:

想法:当金额为奇数时,添加一张五美元的钞票。然后将两张美元的钞票相加,直到剩余的金额是十的倍数。

function giveChange(amount) {
    var ch = { two:0, five:0, ten:0 };

    if ( amount < 2 || amount == 3 ) return;

    if ( amount % 2 ) {
        amount -= 5;
        ch.five = 1;
    }   
    
    while ( amount % 10 ) {
        amount -= 2;
        ch.two ++;
    }

    ch.ten = amount/10;

    return ch;
}

console.log(giveChange(12));
console.log(giveChange(27));
console.log(giveChange(33));

如果你使用Math.floor,你也可以跳过while循环:

function giveChange(amount) {
    var ch = { two:0, five:0, ten:0 };

    if ( amount < 2 || amount == 3 ) return;

    if ( amount % 2 ) {
        amount -= 5;
        ch.five ++;
    }
  
    ch.ten = Math.floor(amount/10);

    ch.two = (amount % 10)/2;

    return ch;
}

console.log(giveChange(12));
console.log(giveChange(27));
console.log(giveChange(33));

【讨论】:

  • 就是这样,我对大量数字进行了测试,结果很顺利,准确!!!我想这很简单,对吧?
  • @Platiplus:我想也是。请注意,while 循环最多转 4 圈。
  • 是的,我问的更像是用更少的行数。但该死的,这正是我当时所需要的。
  • @Platiplus:你甚至不需要这个 while 循环,看看我的编辑。
  • 不知道为什么这被否决了。您的代码运行良好,是 codingame.com JavaScript 评估问题的答案。干杯!
【解决方案3】:

您可以采用组合算法并在数组中返回分母

function combine(array, sum) {

    function c(left, right, sum) {
        if (!sum) {
            result = right;
            return true;
        }
        return left.some(function (a, i, aa) {
            return a <= sum && c(aa.slice(i + (a > sum - a)), right.concat(a), sum - a);
        });
    }

    var result = [];
    c(array.sort(function (a, b) { return b - a; }), [], sum);
    return result;
}

function giveChange(change) {
    return combine([10, 5, 2], change);
}

console.log(giveChange(7));
console.log(giveChange(13));
console.log(giveChange(23));

【讨论】:

  • 虽然我有点迷失在语法上,而且这非常有效,但它并不能解决问题,因为在上述情况下,当我们尝试返回时,我没有返回正确的更改13 美元或 23 美元,我们最终会在此过程中损失 1 美元。返回 13 美元的最有效和正确的方法是 [0,1,4]。此外,我必须在具有两个、五个、十个属性的对象内返回这些值。
  • 确实有效。如果我理解得很好,您会构建所有可能的组合以提供正确的数量,然后对它们进行排序以选择最短的?
  • 优点是可以搭配任意一套账单使用。
  • 这真是太聪明了,但我得承认我真的迷路了。
【解决方案4】:

这是我的解决方案,经过测试,效果很好

function caisse(cash){
two =0;
five =0;
ten = 0;

if (cash>10){
rendu = cash%10;
ten = Math.floor(cash/10);
}
if (rendu%2===0){
  two = rendu/2
}
  if (rendu%2==1 && rendu>=5)
{
  five = 1
two = (rendu-5)/2; 
}

  else if (rendu%2==1 && rendu<5){
    two=Math.floor(rendu/2);
}
return {"two :": two, "five :": five, "ten : ": ten};
}

【讨论】:

    【解决方案5】:

    我测试了这段代码,它成功了!

    function caisse(cash){
    var two =0,five=0,ten =0;
    if(cash==1||cash==3){
    return console.log("impossible")
    }else {
    if(cash>9) {ten=(cash-cash%10)/10;
    cash=cash%10;};
    switch (cash){
    case 1 :ten-=1;five=1;two=3;
    break;
    case 2 : two=1;
    break;
    case 3 : ten-=1;five=1;two=4;
    break;
    case 4 :two=2;
    break;
    case 5: five=1;
    break;
    case 6: two=3;
    break;
    case 7: five=1;two=3;
    break;
    case 8: two=4;
    break;
    case 9: five=1; two=2;
     };
    return{
     two:two,
     five:five,
    ten:ten,
    };
      }
    }
    console.log(caisse(50))
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
    猜你喜欢
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多