查找已排序字典的值的总和并将其匹配 - LINQ

时间:2013-09-20 09:06:52

标签: c# linq

我有一个排序的硬币字典 - 每个键都是一枚硬币,价值是该特定面额中可用的硬币数量。现在,给定金额,我想从字典中取出所有与确切金额相匹配的硬币(或者加上该金额的硬币,优先选择性能)。

以下是一些示例方案:

  • 如果我在存储库中有3个硬币,两个1p硬币和一个5p硬币,如果请求是2p,那么我会回赠两个1p硬币,而我的存储库只有一个5p硬币。 / p>

  • 如果我在存储库中有6个硬币,有5个1p硬币和一个5p硬币,如果请求是5p,那么我可以退还前5个1p硬币或者只返回5个硬币,在最少查找方面表现得更好。

  • 如果我在存储库中有2个硬币,有两个1p硬币,如果请求是一个5便士,那么我会抛出一个异常,说明余额不足。

  • 如果我在存储库中有一枚硬币,有一个5便士硬币并且请求是1p,那么我抛出一个异常,说改变不可用。(不确定异常是否是传达这些的正确方法)。

这是班级:

public class CoinRepository :ICoinRepository
{
    private readonly SortedDictionary<Coin, int> repository;

    public CoinRepository()
    {
        repository = new SortedDictionary<Coin, int>();
    }

    public void Add(List<Coin> coins)
    {
        foreach (var coin in coins)
        {
            repository[coin] = repository.ContainsKey(coin) ? repository[coin] + 1 : 1;               
        }
    }

    public Dictionary<Coin, int> GetCoins(int balance)
    {
        if (repository.Count == 0)
            throw new NoBalanceAvailiable();

        //How?
        return new Dictionary<Coin, int>();
    }
}


 public class Coin
   {
     public int CoinValue { get; set; }
    //Has equals, hascode etc implemented. Omitted here for brevity.
   }

我希望有一些LINQ扩展可以解决这个问题,你能帮忙吗?

注意:可以更改任何或所有数据结构,唯一的目的是找到余额。

谢谢, -Mike

1 个答案:

答案 0 :(得分:1)

假设硬币有一个名为Worth的属性,而字典按硬币值递减,则可以这样做:

public Dictionary<Coin, int> GetCoins(int balance)
{
    var result = new Dictionary<Coin, int>();

    foreach (var pair in repository) {
        while (balance - pair .Key.Worth>0 && pair.Value>0 )
        {
            balance -= pair.Key.Worth;  
            pair.Value--;              
            if (!result.ContainKey(coin.key)) result[pair.key] = 0;
            result[coin.key]++;
        } 
        if (balance == 0) break;
    }

    if (balance == 0) { 
        // pair is a struct, so repository does not change when pair.Value is modified,
        // so if we find a solution, repository has to be updated
        foreach (var pair in result) repository[pair.key] -= pair.Value;
        return result;
    }

    return null;
}