【发布时间】:2013-05-02 02:31:29
【问题描述】:
我编写了以下代码,它返回所有可能的方式来表示一定数量的货币,使用具有特定硬币值的货币中的硬币:
IEnumerable<IEnumerable<int>> getCoins(int price)
{
int[] coinValues = new int[] { 1, 2, 5, 10, 20, 50, 100, 200 }; // Coin values
if (coinValues.Contains(price)) yield return new int[] { price }; // If the price can be represented be a single coin
// For every coin that is smaller than the price, take it away, call the function recursively and concatenate it later
foreach (int coin in coinValues.Where(x => x < price))
foreach (IEnumerable<int> match in getCoins(price - coin))
yield return match.Concat(new int[] { coin });
}
这很好用,但例如对于price = 3,它将{1c, 2c} 和{2c, 1c} 视为两种不同的表示。该问题可以通过将所有找到的值存储在 List 中来解决,然后在生成重复项时删除它们,但这样会牺牲代码的生成器性质。可以使用yield return 将代码修改为不包含重复项吗?
【问题讨论】:
-
你应该从生成排序数组开始。
-
顺便说一句,我建议将 coinValues 移动到静态只读数组,而不是在每次调用 getCoins 时重新创建它。