2010-02-28 58 views
3

我的问题是我有一定的金额,可以说552. 我希望将其分成硬币/票据=>所以结果将例如为1x 500 1x 50 1x 2C#2数组分割金额问题

我已经2个阵列此:

double[] CoinValue = {500, 200, 100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01}; 
    uint[] CoinAmount = new uint[CoinValue.Length]; 

我的问题是究竟如何我“告诉”阵500的值应该在countAmount阵列中1 => 1。所以,如果我有。 1000数组CoinAmount数组会知道它需要保存2作为值(2x500 = 1000)。

所以我的最终结果将是这样的事情,让硬币/钞票数量:提前 1×500 1×50 1×2 .......

感谢。

+4

这看起来像功课给我,请编辑您的文章,如果把它添加作业标签是 – 2010-02-28 11:26:06

+0

看到这里讨论的相关(但更困难)的问题:http://stackoverflow.com/questions/1106929/find-all-combinations-of-coins-when-given-some-dollar-value – Xiaofu 2010-02-28 13:06:37

回答

4

如果您想要精确的答案,请不要使用双打。使用小数或整数算术(转换为分)。

我不打算提供完整的源代码,因为这看起来像作业或学习练习,所以我只提供一些提示。

要找出多少笔记一定面额的需要,利用区分的:

int number = (int)(total/sizeOfBill); 

开始与最大的票据和向下运行到最小,以获得为数不多的纸币/硬币,否则你最终可能会有数千美元的硬币而不是几张钞票。

1

使用decimal为此; double很少适用于金钱类型:

double value = 0.3; 
    value -= 0.1; 
    value -= 0.1; 
    value -= 0.1; 
    Console.WriteLine(value); //**not** zero 

无论如何,一个非常粗糙的方法(也假定硬币降序排序,并且所有的值都是非负)如下。如果你没有硬币的最低值(即你有0.5M和0.2M,但没有0.1M,需要发行0.8M - 因为这需要4x0.2M,而不是0.5M + 0.2M +(该死) )

decimal value = 10023.23M; 
    decimal[] CoinValue = { 500, 200, 100, 50, 20, 10, 5, 2, 1, 0.5M, 0.2M, 0.1M, 0.05M, 0.02M, 0.01M }; 

    int[] counts = new int[CoinValue.Length]; 
    for (int i = 0; i < CoinValue.Length; i++) { 
     decimal v = CoinValue[i]; 
     while (value >= v) { 
      counts[i]++; 
      value -= v; 
     } 
    } 
    for (int i = 0; i < CoinValue.Length; i++) { 
     if (counts[i] > 0) { 
      Console.WriteLine(CoinValue[i] + "\t" + counts[i]); 
     } 
    } 
    Console.WriteLine("Untendered: " + value); 
+0

循环太多,它可以使用一个循环完成... :-)没有,当然输出。而且,小数点对于货币操作来说更好。 – AxelEckenberger 2010-02-28 11:36:02

+0

你不觉得while循环可以减少到除法运算吗?循环也应该有> =条件,而不是> – 2010-02-28 11:39:07

0

鉴于你的数组......也可以使用小数当然。

double[] CoinValue = { 500, 200, 100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01 }; 

uint[] result = new uint[CoinValue.Length]; 
double ammount = 552.5; 
double remaining = ammount; 

for (int i = 0; i < CoinValue.Length; ++i) { 
    result[i] = (uint) (remaining/CoinValue[i]); 
    if (result[i] > 0) 
     remaining = remaining % CoinValue[i]; 
} 
2

不是答案:难以解决的问题是您需要考虑的问题。

你描述的造币系统有一个很好的属性,当你从余下的总数中反复“取出”最大面额时,你最终得到的票据/硬币数量最少。仅供参考,一种通过反复选择最大物体来运行的算法被称为“贪婪算法”。在这种情况下,如果您针对最小数量的账单/硬币进行优化,则贪婪算法会给出最佳结果。

你能解决该问题对于造币系统,其中,硬币是:

  • 1冠= 60便士(“便士”是“便士”的复数)
  • 1半冠= 30便士
  • 1弗罗林= 24便士
  • 1先令= 12便士
  • 1坦纳= 6便士

如果您正在为最小数量的硬币进行优化,现在进行更改的贪婪算法不起作用。例如,48便士通过贪婪算法转到

  • 取出的半胎冠,留下18便士
  • 取出先令,留下6便士
  • 取出的Tanner,留下任何

三枚硬币。但显然48便士是两个弗洛林,它只有两个硬币。

你能想出一个算法来处理这个造币系统,并给每个问题可能的最少数量的硬币?

(请注意,预十进制英国造币系统适用于没有小数,也没有双算术,做这一切在整数!)