C# 2 数组分割数量问题

3

我的问题是,我有一定金额的钱,比如说552元。我希望能够将其分成硬币/纸币的形式,例如结果可以是1张500元、1张50元和1枚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。因此,如果我有1000,CoinAmount数组将知道它需要保持2个值(2x500 = 1000)。
所以我的最终结果会像这样,给出硬币/纸币的数量: 1 x 500 1 x 50 1 x 2 .......
提前感谢。

4
这看起来像是一份作业,请编辑您的帖子并添加“作业”标签。 - Otto Allmendinger
请参考这里讨论的相关(但更难)问题:https://dev59.com/pHNA5IYBdhLWcg3wEZaT - Xiaofu
4个回答

4

如果您想要精确的答案,请不要使用double类型,而是使用小数或整数算术(通过转换为分)。

由于这看起来像是作业或学习练习,因此我不会提供完整的源代码,而是给出一些提示。

要找出需要某种面额纸币的数量,请使用除法:

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

从大面额的钞票开始,逐渐往小面额的钞票/硬币转换,这样可以得到较少数量的钞票/硬币,否则你可能会得到成千上万枚一分钱的硬币而不是几张钞票。


2
不是答案:这是一个更难的问题,供您考虑。
您描述的货币系统具有一个很好的特性,即当您反复从剩余总数中“取出”最大面额时,您最终得到的解决方案将拥有最少的钞票/硬币。顺便说一下,一种通过不断选择最大物品来操作的算法称为“贪心算法”;在这种情况下,如果您正在优化最小数量的钞票/硬币,则贪心算法会给出最佳结果。
您能否解决以下货币系统的问题:
1皇冠= 60便士(“pence”是“penny”的复数)
1半皇冠= 30便士
1佛林= 24便士
1先令= 12便士
1塔纳= 6便士
现在,如果您正在优化最小数量的硬币,则贪心算法制作零钱将无法使用。例如,用贪心算法处理48便士:
- 取出半皇冠,剩下18便士 - 取出一先令,剩下6便士 - 取出一塔纳,没有剩余的便士
需要三个硬币。但显然,48便士是两个佛林,只需要两个硬币。
您能否想出一种处理此货币系统并为每个问题提供最少数量的硬币的算法?
(请注意,英国十进制前的货币系统既不适用于十进制也不适用于双倍算术;请全部使用整数!)

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);

太多的循环,可以使用一个循环完成... :-) 当然,没有输出。是的,对于货币运算来说,小数更好。 - AxelEckenberger
你不觉得while循环可以简化为一个除法操作吗?此外,循环应该使用>=条件,而不是>。 - George Polevoy

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];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接