Coin change in C# with limited coins

一个人想着一个人 提交于 2019-12-25 02:03:19

问题


I built the following coin change (C#) that works perfectly:

class Program
    {

        static int amount = 0;

        static void Main(string[] args)
        {

            EnterAmount();

            int[] coins = new int[] { 500, 100, 50, 20, 10, 5, 2, 1 };

            int Results = 0;

            for (int i = 0; i < coins.Length; i++)
            {
                    Results = amount / coins[i];
                    Console.WriteLine(Results + " x " + coins[i]);
                    amount -= Results * coins[i];
            }
        }

        static void EnterAmount()
        {
            Console.Out.WriteLine("Enter an amount : ");
            amount = int.Parse(Console.ReadLine());
        }
    }

My problem is that I don't know how to limit the quantity of coins for every coin. For exemple, I would like to have a maximum number of 4 coins of €500, 6 coins of €10, 5 coins of €2, etc. And it would be awesome that the coin change returns the number of coins used for every coin.

Can you help me please? Thank you.


回答1:


Be aware that this code just answers your question about who to limit your coins number, but your algorithm is not complete as you don't consider a lot of corner cases.

static void Main(string[] args)
{
    var amount = 100000;

    var availabeCoins = new CoinPack[] 
    { 
        new CoinPack { Value = 500, Amount = 2 },
        new CoinPack { Value = 100, Amount = 3 },
        new CoinPack { Value = 50, Amount = 5 },
        new CoinPack { Value = 20, Amount = 1 },
        new CoinPack { Value = 10, Amount = 2 },
        new CoinPack { Value = 5, Amount = 0 },
        new CoinPack { Value = 2, Amount = 10 },
        new CoinPack { Value = 1, Amount = 500 }
    };

    var usedCoins = new CoinPack[] 
    { 
        new CoinPack { Value = 500 },
        new CoinPack { Value = 100 },
        new CoinPack { Value = 50 },
        new CoinPack { Value = 20 },
        new CoinPack { Value = 10 },
        new CoinPack { Value = 5 },
        new CoinPack { Value = 2 },
        new CoinPack { Value = 1 }
    };

    for (int i = 0; i < availabeCoins.Length; i++)
    {
        usedCoins[i].Amount = amount / availabeCoins[i].Value;
        if (usedCoins[i].Amount > availabeCoins[i].Amount)
        {
            usedCoins[i].Amount = availabeCoins[i].Amount;
        }

        amount -= usedCoins[i].Amount * usedCoins[i].Value;
    }

    foreach (var usedCoin in usedCoins)
    {
        Console.WriteLine(usedCoin.Value + " " + usedCoin.Amount);
    }
}

class CoinPack
{
    public int Value;
    public int Amount;
}

UPD This solution is pretty inefficient, but I guess it solves your problem. You can take it as a reference and improve it yourself.

void Main(string[] args)
{
    var amount = 6;

    var availabeCoins = new List<CoinPack>
    { 
        new CoinPack { Value = 500, Amount = 0 },
        new CoinPack { Value = 100, Amount = 0 },
        new CoinPack { Value = 50, Amount = 0 },
        new CoinPack { Value = 20, Amount = 0 },
        new CoinPack { Value = 10, Amount = 0 },
        new CoinPack { Value = 5, Amount = 1 },
        new CoinPack { Value = 2, Amount = 3 },
        new CoinPack { Value = 1, Amount = 0 }
    };

    var usedCoins = new List<CoinPack>
    { 
        new CoinPack { Value = 500, Amount = 0 },
        new CoinPack { Value = 100, Amount = 0 },
        new CoinPack { Value = 50, Amount = 0 },
        new CoinPack { Value = 20, Amount = 0 },
        new CoinPack { Value = 10, Amount = 0 },
        new CoinPack { Value = 5, Amount = 0 },
        new CoinPack { Value = 2, Amount = 0 },
        new CoinPack { Value = 1, Amount = 0 }
    };

    if (Change(amount, availabeCoins, usedCoins) != null)
    {
        foreach (var usedCoin in usedCoins)
        {
            Console.WriteLine(usedCoin.Value + " " + usedCoin.Amount);
        }
    }
    else
    {
        Console.WriteLine("Cannot find exact change");
    }
}

List<CoinPack> Change(int amount, List<CoinPack> availableCoins, List<CoinPack> usedCoins)
{
    if (amount == 0)
    {
        return availableCoins;
    }

    if (amount < 0)
    {
        return null;
    }

    foreach (var availableCoin in availableCoins.Where(ac => ac.Amount > 0 && amount >= ac.Value))
    {
        var newAvailableCoins = CopyCoins(availableCoins);
        newAvailableCoins.First(c => c.Value == availableCoin.Value).Amount--;
        var change = Change(amount - availableCoin.Value, newAvailableCoins, usedCoins);

        if (change == newAvailableCoins)
        {
            usedCoins.First(c => c.Value == availableCoin.Value).Amount++;
            return availableCoins;
        }
    }

    return null;
}

List<CoinPack> CopyCoins(List<CoinPack> coinPacks)
{
    var copy = new List<CoinPack>();
    foreach (var coinPack in coinPacks)
    {
        copy.Add(new CoinPack { Value = coinPack.Value, Amount = coinPack.Amount });
    }
    return copy;
}

class CoinPack
{
    public int Value;
    public int Amount;
}



回答2:


I think this will be helpfull:

using System;
using System.Data;
using System.IO;

namespace ConsoleApplicationTests
{
    class Program
    {
        static int amount = 321370;

        static void Main(string[] args)
        {
            Coin[] c = new Coin[] { new Coin(500, 7), new Coin(200, 3), new Coin(100, 5) ,
                                    new Coin(50, 6), new Coin(20, 2), new Coin(10, 4),
                                    new Coin(5, 0), new Coin(2, 5), new Coin(1, 3)};
            int netAmount = amount;

            for (int i = 0; i < c.Length; i++)
            {
                amount -= c[i].coveredPrice(amount);
            }

            for (int i = 0; i < c.Length; i++)
            {
                Console.WriteLine(c[i].ToString());
            }

            Console.ReadLine();

        }
    }

    class Coin
    {
        private int price;
        private int counted;    // You can continue your bank for next amount too.
        private int maxNo;

        public Coin(int coinPrice, int coinMaxNo)
        {
            this.price = coinPrice;
            this.maxNo = coinMaxNo;
            this.counted = 0;
        }

        public int coveredPrice(int Price)
        {
            int Num = Price / price;
            if (maxNo == 0)
                return 0;
            if (maxNo != -1)             //-i is infinit
                if (Num > this.maxNo - this.counted)
                    Num = maxNo;
            this.counted += Num;
            return Num * price;
        }

        //public int getPrice() { return this.price; }
        //public int getCount() { return this.counted; }
        //public int getMax() { return this.maxNo; }
        public override string ToString()
        {
            return string.Format("{0} x {1} (max {2}) ", this.price.ToString(), this.counted.ToString(), this.maxNo.ToString());
        }
    }
}


来源:https://stackoverflow.com/questions/28916675/coin-change-in-c-sharp-with-limited-coins

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!