如何获取字典中指定数字的最近键?

时间:2015-12-14 14:18:35

标签: c# math dictionary

我有一个Excel函数,我正在尝试将其转换为C#等效代码。该功能(在Excel中)如下:

WorksheetFunction.VLookup(number, Range("numberDictionary"), 2, True)

基本上这个功能的作用是......

假设存在字典,定义如下:

Number | Value
1      | 2
3      | 8
9      | 1

假设我的参数'number'等于2

我希望返回的值 8 ,因为查找函数会将输入数字2舍入到范围(3)中最接近的数字,然后返回相关值。

有谁能告诉我如何在C#代码中实现同样的目标?假设使用Dictionary<int, int>()

非常感谢提前

伊恩

3 个答案:

答案 0 :(得分:0)

您可以利用Keys的{​​{1}}属性:

IDictionary<TKey, TValue>

答案 1 :(得分:0)

如果您坚持使用字典,可以使用以下LINQ查询:

Dictionary<int, int> dictionary = new Dictionary<int, int>() { 
    {1,2} ,{3,8} ,{9,1} 
};

int searchKey = 2;
int value;

if (dictionary.ContainsKey(searchKey))
    value = dictionary[searchKey];
else
{
    int nearestKey = dictionary.Keys
        .Select(i => new { Value = i, Diff = Math.Abs(i - searchKey) })
        .OrderBy(x => x.Diff)
        .ThenBy(x => x.Value > searchKey ? 0 : 1) // in case of ties you want the higher number
        .Select(x => x.Value)
        .First();
    value = dictionary[nearestKey];
}

这将是O(n),因为您必须查看所有密钥。如果您可以使用有序集合和二进制搜索算法,那么它将是O(log n)。因此,您可以使用SortedDictionary<TKey, TValue>SortedList<TKey, TValue>Differences

使用SortedList,您可以使用this extension method。然后很简单:

int index = dictionary.FindFirstIndexGreaterThanOrEqualTo(2);
int value = dictionary[dictionary.Keys[index]];

答案 2 :(得分:0)

        var input = 2;
        var dictionary = new Dictionary<int, int> { { 1, 2 }, { 3, 8 }, { 9, 1 } };

        var smallestDifference = int.MaxValue;
        var keys = new List<int>();

        if (dictionary.ContainsKey(input))
        {
            return dictionary[input];
        }

        foreach (var entry in dictionary)
        {
            var difference = entry.Key - input;
            if (difference < smallestDifference)
            {
                smallestDifference = difference;
                keys = new List<int>() { entry.Key };
            }
            else if (difference == smallestDifference)
            {
                keys.Add(entry.Key);
            }
        }

        var candidates = dictionary.Where(x => x.Key == smallestDifference).ToList();
        if ( candidates.Count == 1)
        {
            return candidates.SingleOrDefault();
        }
        return candidates.SingleOrDefault(y => y > input);