简单ATM算法

  • 本文关键字:算法 ATM 简单 c#
  • 更新时间 :
  • 英文 :


我有一个简单的ATM算法,给定要取的金额,它应该交付100张、50张和20张钞票中的最小金额。

var amount = 280;
var availableBiils = new[] { 100, 50, 20 };
var usedNumberOfBills = new[] { 0, 0, 0 };
for (var i = 0; i < availableBiils.Count(); i++)
{
var bill = availableBiils[i];
while (amount >= bill)
{
amount = amount - bill;
usedNumberOfBills[i] += 1;
}
}
for (var i = 0; i < usedNumberOfBills.Length; i++)
{
Console.WriteLine($"{availableBiils[i]}    {usedNumberOfBills[i]}");
}

我的方法在某些情况下不起作用,例如280、260、240等等。

这是我刚刚为您创建的一个工作示例。

这是处理整个事务的结构体:


struct AmountManager
{
private int amount = 0;
private List<int> specialAmount = new List<int> { 80, 60 };
public AmountManager(int amount)
{
this.amount = amount;
}
List<int> Notes = new List<int> { 100, 50, 20 };
/// <summary>
/// Checks how many 100 notes can be used given the amount.
/// </summary>
/// <returns>taple representing the number of 100 notes to be used, and the remaining amount</returns>
public (int Quotient, int Remainder) HundredsUsed() 
=> Math.DivRem(amount, Notes[0]);

/// <summary>
/// Checks how many 50 notes can be used given the remaining amount from the HundredsUsed().
/// </summary>
/// <returns>taple representing the number of 50 notes to be used, and the remaining amount</returns>
public (int Quotient, int Remainder) FiftiesUsed()
{
if (HundredsUsed().Remainder == 0) 
return (0, 0);
if (specialAmount.Contains(HundredsUsed().Remainder))
return (0, HundredsUsed().Remainder);
else
return Math.DivRem(HundredsUsed().Remainder, Notes[1]);
}
/// <summary>
/// Checks how many 20 notes can be used given the remaining amount from the FiftiesUsed().
/// </summary>
/// <returns>taple representing the number of 20 notes to be used, and the remaining amount</returns>
public (int Quotient, int Remainder) TwentiesUsed()
=> (FiftiesUsed().Remainder < Notes[2]) ? (0, 0) :  Math.DivRem(FiftiesUsed().Remainder, Notes[2]);
public string Print()
=> $@"{Notes[0]}({HundredsUsed().Quotient}), {Notes[1]}({FiftiesUsed().Quotient}), {Notes[2]}({TwentiesUsed().Quotient})";
}

创建一个控制台应用程序,并创建一个这个结构体的实例:AmountManager transact = new AmountManager(YourNumber)然后运行打印方法transact.Print();

我用以下值测试了它:

  • 220-返回100(2), 50(0), 20(1)
  • 260-返回100(2), 50(0), 20(3)
  • 270-返回100(2), 50(1), 20(1)
  • 290-返回100(2), 50(2), 20(1)

你的独特问题是当你有60或80。在这种情况下,你拿了50个,剩下10到30个你解决不了。请检查这些情况。

var amount = 280;
var availableBiils = new[] { 100, 50, 20 };
var usedNumberOfBills = new[] { 0, 0, 0 };
for (var i = 0; i < availableBiils.Count(); i++)
{
var bill = availableBiils[i];
while (amount >= bill)
{
if (amount == 60)
{
amount = 0;
usedNumberOfBills[2] += 3;
}
else if (amount == 80)
{
amount = 0;
usedNumberOfBills[2] += 4;
}
else
{
amount = amount - bill;
usedNumberOfBills[i] += 1;
}
}
}
for (var i = 0; i < usedNumberOfBills.Length; i++)
{
Console.WriteLine($"{availableBiils[i]}    {usedNumberOfBills[i]}");
}

如果你的可用账单是众所周知的,你也可以这样做:

var amount = 280;
var availableBiils = new[] { 100, 50, 20 };
var usedNumberOfBills = new[] { 0, 0, 0 };

usedNumberOfBills[0] = Math.DivRem(amount, 100, out int pending);
if (pending != 60 && pending != 80)
{
usedNumberOfBills[1] = Math.DivRem(pending, 50, out amount);
usedNumberOfBills[2] = amount / 20;
}
else
{
usedNumberOfBills[2] = pending / 20;
}
for (var i = 0; i < usedNumberOfBills.Length; i++)
{
Console.WriteLine($"{availableBiils[i]}    {usedNumberOfBills[i]}");
}

您的算法将只适用于每个金额,如果对于每个账单(不包括最低),您至少有一个账单,该除法给出整数。对于50来说,只有较低的账单是20,但50/20=2.5,所以不是整数。

最简单的办法是加10元。

最新更新