硬币找零算法JS

时间:2018-12-09 18:08:11

标签: javascript if-statement coin-change

3-4天内,我一直在尝试为此算法提供解决方案,但是似乎没有任何效果,可用的解决方案对我来说要先进一些。它仅需使用条件即可解决,因此无需递归或动态编程。

在以下面额中,我需要确定进行找零所需的最少硬币数量:1、0.5、0.2、0.1、0.05、0.02和0.01。

输入如下:

一件物品的价格

客户支付的金额

当前想法:

let price = +gets();
let paidSum = +gets();
//gets is used to accept number input
let change = paidSum - price;

我认为我可以使用Math.floor来分离整数部分并将其减去,但是我不知道该如何处理剩余的总和。

取模是否可以测试剩余的总和是否包含任何剩余的要更改的值,然后再次相减直到我达到零?

我确实意识到这不是最好的提法,但是我在这里很茫然,除此以外,我还完成了其他所有任务。谢谢。

3 个答案:

答案 0 :(得分:1)

使用您指定的面额,此问题比一般的change making problem更简单。在这种实际情况下,我们可以确定使用最大面额(不大于要支付的面额)始终可以得出最佳解决方案。

因此,不需要递归或动态编程。只需一个简单的循环即可。

在这里,我将忽略获得票据价格和客户支付金额的额外“层”。最后,唯一重要的是要还给客户的零钱。因此,此代码段要求提供找零金额,并返回需要找零的硬币。

function getChange(amount) {
    amount *= 100; // Convert to number of cents
    var denominations = [1, 2, 5, 10, 20, 50, 100]; // cents
    var result = [];
    while (amount > 0) {
        var coin = denominations.pop(); // Get next greatest coin
        var count = Math.floor(amount/coin); // See how many times I need that coin
        amount -= count * coin; // Reduce the amount with that number of coins
        if (count) result.push([coin/100, count]); // Store count & coin
    }
    return result;
}

// I/O management

change.oninput = function () {
    var coins = getChange(this.value);
    result.textContent = coins.map(([coin, count]) => `${count} x $${coin}`).join(" + ");
};
To be paid to customer: <input id="change">
<div>Coins to pay: <span id="result"></span></div>

答案 1 :(得分:0)

var coins;
var coinArray = {};
var output = {};


/* Method to get coin value without decimal point - it is required because 
* javascript will consider 5.6 as 6 if we do Math.round()
*/
function getRoundFigureCoinValue(x) {
    return (x * 10 - ((x * 10) % 10)) / 10;
}

// Method to calculate possible combination of coins
function calculateCoins(input) {
    let largestPossibleCoin = 1;

    if (input) {
        coins.forEach((x) => {
            if (input >= x) {
                largestPossibleCoin = x;
            }
        });
        let remainingCents = input % largestPossibleCoin;
        output[largestPossibleCoin] = getRoundFigureCoinValue(
            (input / largestPossibleCoin).toFixed(1)
        );
        if (remainingCents && input > 1) {
            calculateCoins(remainingCents);
        }

        return largestPossibleCoin;
    }
}

// Method to be called to get output.
function calculatePossibleCoinCombinations(value) {
    if (isNaN(value) || +value <= 0) {
        console.log('Invalid input');
        return;
    } else {
        console.log('Possible combinations are:')
        value = +value;
    }

    coins = [1, 5, 10, 25];
    while (coins.length) {
        let largestPossibleCoin = calculateCoins(value) || 0;
        let outputString = '';
        coins = coins.filter((x) => x < largestPossibleCoin);
        Object.keys(output).forEach((key) => {
            outputString += `${output[key]} - ${key} cents; `;
        })
        console.log(outputString);
        output = {};
    }
}


/*
Sample inputs:
 calculatePossibleCoinCombinations('89');
 calculatePossibleCoinCombinations(10);
 calculatePossibleCoinCombinations(0);
 calculatePossibleCoinCombinations('someString');
 calculatePossibleCoinCombinations(-10)
*/

答案 2 :(得分:0)

简单,反转和映射面额(以美分计),然后返回一个新数组,其中包含每种面额所需的硬币数量。

const coinsCents = [1, 2, 5, 10, 20, 50, 100]
const getChange = (amountInCents) => {
    return coinsCents.reverse().map(coin => {
        let amountCoin = Math.floor(amountInCents/coin)
        amountInCents -= amountCoin * coin
        return amountCoin
    }).reverse()
}