【发布时间】:2009-08-29 22:04:51
【问题描述】:
为了好玩,我希望看到有人使用和滥用 LINQ 来解决这个金钱问题。 我真的不知道你会怎么做 - 我想填充一些集合然后选择它。
如果给定硬币的总数并给出所有硬币的总和: 显示所有可能的硬币组合。硬币有夸特 (.25)、角钱 (.10) 镍 (.05) 和便士 (.01)
包含该选项,以便一种硬币可以有零个,或者每种硬币必须至少有一个。
示例问题:如果我有 19 个硬币,硬币加起来是 1.56 美元,那么每种硬币必须至少有 1 个。
答案是:
1 夸特,9 硬币,8 镍币,1 便士
2 夸特,5 个硬币,11 个镍币,1 个便士
2 夸特,9 角钱,2 镍币,6 便士
3 夸特,1 硬币,14 镍,1 便士
3 夸特,5 个硬币,5 个镍币,6 个便士
4 夸特,1 硬币,8 镍币,6 便士
5 夸特,1 硬币,2 镍币,11 便士
如果我们允许硬币为零,我们允许获得额外的硬币 0 夸特,13 硬币,5 镍币,1 便士
这里是一些示例 C# 代码,使用蛮力方法来解决问题。 不用费心改进示例,让我们看看使用 Linq 的解决方案。 //如果可能,尽量不要使用任何常规的 c# 循环代码。
private void SolveCoinProblem(int totalNumberOfCoins, double totalAmount, int minimumNumberOfEachCoin)
{
int foundCount = 0;
long numberOfTries = 0;
Console.WriteLine(String.Format("Solving Coin Problem:TotalNumberOfCoins={0}TotalAmount={1}MinimumNumberOfEachCoin{2}", totalNumberOfCoins, totalAmount, minimumNumberOfEachCoin));
for (int totalQuarters = minimumNumberOfEachCoin; totalQuarters < totalNumberOfCoins; totalQuarters++)
{
for (int totalDimes = minimumNumberOfEachCoin; totalDimes < totalNumberOfCoins; totalDimes++)
{
for (int totalNickels = minimumNumberOfEachCoin; totalNickels < totalNumberOfCoins; totalNickels++)
{
for (int totalPennies = minimumNumberOfEachCoin; totalPennies < totalNumberOfCoins; totalPennies++)
{
numberOfTries++;
if (totalQuarters + totalDimes + totalNickels + totalPennies == totalNumberOfCoins)
{
if (Math.Round((totalQuarters * .25) + (totalDimes * .10) + (totalNickels * .05) + (totalPennies * .01),2) == totalAmount)
{
Console.WriteLine(String.Format("{0} Quarters, {1} Dimes, {2} Nickels, {3} Pennies", totalQuarters, totalDimes, totalNickels, totalPennies));
foundCount++;
}
}
}
}
}
}
Console.WriteLine(String.Format("{0} Combinations Found. We tried {1} combinations.", foundCount, numberOfTries));
}
【问题讨论】:
-
使用 LINQ 来解决这个问题绝不是滥用! :-)
-
顺便说一句,您的代码找到 5 个(而不是 7 个)答案的原因是舍入错误。始终切换为十进制(0.05M 等),您可能会感到惊讶!
-
Re "floating point BS" - 那不是 BS;这就是浮点的工作原理。经验法则:如果您在同一个句子中看到“float”(或“double”)和“money”,则可能是错误的。