问题
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