【问题标题】:Greedy Algorithm in JavaScriptJavaScript 中的贪心算法
【发布时间】:2015-06-27 16:21:26
【问题描述】:

这是我需要咨询的问题:

编写一个贪心算法,用尽可能少的硬币找零 使用贪心算法。给你一个硬币值数组和 金额:computeChange(coins, amount)。返回一个数组 每个硬币的计数。

例如:computeChange([50, 25, 10, 5, 1], 137) 应该返回 数组[2, 1, 1, 0, 2],表示每个硬币有多少:2 50 美分,1 夸特(25 美分),1 角钱(10 美分),无镍币(5 美分)和 2 便士(1 美分),加起来是 137 美分。

您从 computeChange 返回的数组的长度应与 第一个论点(硬币)。假设硬币包含 不同的硬币类型按降序排列。

贪心算法说你反复寻找最大的 硬币小于或等于剩余金额,则 从剩余金额中减去该硬币。当剩下的 金额达到零(或更少),返回使用的硬币计数。 (这 算法并不总是最优的。)

您可以更改变量COINS,它给出了 你可以用不同的硬币来找零,还有AMOUNT,这是 要进行的更改的总价值。更改这些值可能是 对调试程序很有用。

这是我的代码,但它没有显示 36 美分的标准变化。谁能帮我?谢谢。

<html>
<head>
    <title>The Greedy Algorithm</title>

    <script>

// ======== Here is the problem to be solved:   ========
COINS = [50, 25, 10, 5, 1];
AMOUNT = 137
coincount = [0,0,0,0,0];

// ======== Here is where your solution begins: ========

// define the function named computeChange here:
function computeChange(coins, amount) {
  var i = 0; var creminder = AMOUNT; var ccoin; 

    while( i < COINS.length )
    {
      while ( COINS[i] <= creminder )
      {
        creminder = creminder - COINS[i];
        ccoin = coincount [i] ;
        ccoin += 1;
        coincount [i] = ccoin ;

      }

      i++;
    }

    return coincount;
}

// ===================================================================
// ======== Everything below here simply displays your output ========
// ======== Do NOT change anything below this line ===================
// ===================================================================


function rightJustify(s, w) {
    // return a string of width w with s in the rightmost characters and
    // at least one space on the left. For simplicity, assume w < 20.
    var slen = s.length;
    var blanks = "                    "
    return blanks.substr(0, Math.min(20, Math.max(1, w - slen))) + s;
}


function makeChange() {
    // compute change as an array: each element of change tells
    // how many of the corresponding value in COINS to give. The
    // total value should equal AMOUNT.
    var change = computeChange(COINS, AMOUNT);
    // now format the results. Output should look like:
    // NUMBER   VALUE
    //    1       50
    //    0       25
    //    1       10
    //    1        5
    //    3        1
    // TOTAL AMOUNT: 68 (total is correct)
    //
    // First, we'll do some type checking in case change is not of the
    // expected type.
    change = [].concat(change); // force whatever it is to be an array
    // it should be an array of numbers, so let's check
    for (i = 0; i < change.length; i++) {
        if (typeof(change[i]) != 'number') {
            return "Error: the function computeChange did not return " +
                   "an array of numbers.";
        }
    }
    if (change.length > COINS.length) {
        return "Error: the function computeChange returned an array " +
               "longer than the length (" + COINS.length + ") of COINS.";
    }
    if (change.length < COINS.length) {
        return "Error: the function computeChange returned an array " +
               "shorter than the length (" + COINS.length + ") of COINS.";
    }
    var output = "<pre>NUMBER   VALUE\n"
    var sum = 0;
    for (i = 0; i < change.length; i++) {
        sum += change[i] * COINS[i];
        var n = change[i].toString();
        var a = COINS[i].toString();
        output += rightJustify(n, 4) + rightJustify(a, 9) + "\n";
    }
    output += "TOTAL AMOUNT: " + sum + " (total is ";
    output += (sum == AMOUNT ? "correct" :
                               "incorrect, should be " + AMOUNT) + ")\n";
    return output;
}


function runSolution()
{
    parent.console.log('loaded, calling runSolution()\n');
    parent.console.log('answer: ' + document.getElementById('answer').toString());
    document.getElementById('answer').innerHTML = makeChange();
}

    </script>
</head>
<body>
    <!-- the output is displayed using HTML     -->
    <!-- the ? will be replaced with the answer -->
    <div id = "answer">?</div></p>
    <br>
    <script>runSolution();</script>
</body>
</html>

【问题讨论】:

  • 什么意思它没有显示 36 美分的标准变化。 ?
  • 我的意思是我的代码有什么问题,或者我需要做什么才能显示 36 美分硬币的标准零钱?因为我一直在尝试和在互联网上搜索大多数示例都是用 VB 和其他编程语言编写的,而不是 javascript。
  • 您的意思是,您希望问题的值从 137 变为 36?

标签: javascript algorithm


【解决方案1】:

想法: 看了回复,首先想到的可能是这里没有看到的其他代码,所以我们需要使函数足以通过输入解决问题,而不是像AMOUNT那样使用GLOBAL VALUESCOINScoincount,而是使用 coinsamount 等给定的参数,并返回自创建的 coincount

我会在代码中直接使用cmets来解释这个

function computeChange(coins, amount) {
    // Create a array that is used to return the final result, instead of the global one.
    var coincount = [];

    // use the given `amount` to set `creminder ` rather than `AMOUNT` which may not be accessible if your code is called otherplace rather than here.
    var i = 0; var creminder = amount; var ccoin;


    while( i < coins.length )
    { 
      // Lazily init the used coin for coin type i to 0.
      coincount[i] = 0;
      while ( coins[i] <= creminder )
      {
        creminder = creminder - coins[i];
        ccoin = coincount[i];
        ccoin += 1;
        coincount[i] = ccoin;
      }

      i++;
    }

    return coincount;
}

你的原始版本的creminder是由AMOUNT决定的,所以无论我调用computeChanges(COINS, AMOUNT)还是computeChanges(COINS, 37),结果都是一样的,因为第二个例子中的37没有使用,忽略并且creminder 仍设置为AMOUNT。 Nina Scholz 和我所做的都是给定 amount 帐户,因此当您的函数生成结果集时很重要。

【讨论】:

【解决方案2】:

一些备注:

  • 您将获得 coinsamount 的值。原始功能访问 COINSAMOUNT,即使有这个值的本地副本。

  • creminder 不是必需的,因为你有amount

  • ccoin不是必须的,因为你可以直接从金额中减去所选硬币的价值。

var COINS = [50, 25, 10, 5, 1],
    AMOUNT = 36; //137

function computeChange(coins, amount) {
    var i = 0,
        coincount = coins.map(function () { return 0; }); // returns an array and for each element of coins zero
    while (i < coins.length) {
        while (coins[i] <= amount) {
            amount -= coins[i];
            coincount[i]++;
        }
        i++;
    }
    return coincount;
}
out(JSON.stringify(computeChange(COINS, AMOUNT), null, 4), true);

function out(s, pre) {
    var descriptionNode = document.createElement('div');
    if (pre) {
        var preNode = document.createElement('pre');
        preNode.innerHTML = s + '<br>';
        descriptionNode.appendChild(preNode);
    } else {
        descriptionNode.innerHTML = s + '<br>';
    }
    document.getElementById('out').appendChild(descriptionNode);
}
&lt;div id="out"&gt;&lt;/div&gt;

【讨论】:

  • 嗨 Nina,我在代码中试过了。输出变成了这样:?检查您的代码...
  • 你能解释一下这段代码是什么意思吗
  • function computeChange(coins, amount) { var i = 0, coincount = coin.map(function () { return 0; }); while (i
  • 我输入这段代码的那一刻,输出变成了这样:
  • NUMBER VALUE 0 50 1 25 1 10 0 5 1 1 总金额:36(总数是正确的)检查您的代码...结果是正确的数字数组长度:是标准更改为 36 美分:是 1.37 美元的标准零钱:是 85 美分的奇怪硬币:是的,只用便士找零:是的
【解决方案3】:

虽然上面的答案非常正确,但我认为人们也可以用不同的方式来思考这个特定问题的解决方案。

computeChange([50, 25, 10, 5, 1], 137) 为例,可以使用单个循环来获得所需的解决方案。

function computeChange(changeArray, amount) {
  const result = [];

  for (let i = 0; i < changeArray.length; i++) {
    let changeAmount = Math.floor(amount / changeArray[i]);
    amount -= (changeArray[i] * changeAmount);

    result.push(changeAmount);

  }
  return result;
}

computeChange([50, 25, 10, 5, 1], 137); //  [2, 1, 1, 0, 2]

【讨论】:

    【解决方案4】:
    function cc(c, a) {
        for (var ra=[],i=0,r=a; i<c.length; ra[i] = (r/c[i])|0, r -= ra[i]*c[i], i++); 
        return ra;
    }
    
    function cc2(c, a) {
        return c.map((c, i) => { var t = (a/c)|0; a -= c*t; return t; })
    }
    
    cc([50, 25, 10, 5, 1], 137);  //  [2, 1, 1, 0, 2]
    cc2([50, 25, 10, 5, 1], 137); //  [2, 1, 1, 0, 2]
    

    【讨论】:

      猜你喜欢
      • 2023-04-02
      • 2022-12-07
      • 2019-04-27
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多