C#查找字典

时间:2009-08-31 18:47:55

标签: c#

我目前正在尝试创建一个根据信号强度估算位置的程序。信号强度值是一个int,然后我需要一个带范围的查找字典。

所以我会有类似的东西:

Signal Strenth             Position
0-9                            1
10-19                          2
20-29                          3

然后我想查看信号强度所涉及的位置,例如15与位置2有关。

我知道我可以加载一些if语句但是有一种很好的方法可以使用某种查找字典吗?

9 个答案:

答案 0 :(得分:11)

怎么样:

int position = signalStrength / 10 + 1;

善,

答案 1 :(得分:11)

如果您有任意但连续的范围,您可以使用上限数组并执行二分搜索以获得该位置:

// Definition of ranges
int[] ranges = new int[] { 9, 19, 29 };

// Lookup
int position = Array.BinarySearch(ranges, 15);
if (position < 0)
    position = ~position;

// Definition of range names
string[] names = new string[] { "home", "street", "city", "far away" };

Console.WriteLine("Position is: {0}", names[position]);

Array.BinarySearch返回数组中项的索引(如果数组必须显式排序)或者应该插入项的按位反转索引,以保持数组的排序。

答案 2 :(得分:2)

当您想使用Dictionary时,至少需要一些特殊的键类型来处理范围。 KeyType可以是抽象的,也可以是两个派生类型KeyTypeRange(int int)和KEyTypeSearch(int)。必须实现一些特殊的比较逻辑来比较KeyTypeSearch和KeyTypeRange。

SortedDictionary<KeyType,int>  lookup = new Dictionary<int,int>();
lookup.Add( new KeyTypeRange(1,10),1);
lookup.Add( new KeyTypeRange(11,20),2);
lookup.Add( new KeyTypeRange(21,30),3);
lookup.TryGetValue( new KeyTypeSearch(15) );

它显示了在字典中使用不同的搜索键和键值的可能解决方案。但对于这个问题,这似乎是矫枉过正。 BinarySearch解决方案可以最好地解决这个问题。

答案 3 :(得分:1)

善是目的的功能。所有上述解决方案都可以很好地假设任何给定范围都是少数整数。否则,您可能希望使用真实世界的数学函数来确定您的组。例如,对于给出的示例,您的答案函数将是x%10 + 1;这比字典运行得快得多。

答案 4 :(得分:0)

你可以做一个Dictionary,其中第一个int是信号强度,第二个int是位置。您需要为范围中的每个值添加一个条目(因此,一个用于信号强度0,位置1,信号强度1,位置1等),但这将是一个非常快速的单行查找。

类似的东西:

Dictionary<int, int> values;

values = new Dictionary<int, int>();

values[0] = 1;
values[1] = 1;
...
values[29] = 3;

然后,访问它:

Console.WriteLine(values[27].ToString());

答案 5 :(得分:0)

为了将来的扩展,我会做2本词典。 以防这些费率变化  所以

dictionary<string,dictionary<int,int>>

或只使用自定义类 字符串是静态字符串,如低中,高,然后你可以改变你的foreach中的范围初始化初始值

答案 6 :(得分:0)

一种解决方案是使用简单列表,其中列表中的每个位置代表您正在扫描的不同位置。在代码中,它可能看起来像这样(假设所有位置编号都是连续的):

**注意:我实际上没有运行此代码以确保其按原样运行...您可能还需要在IEqualityComparer上实现Range以便{{1}操作返回正确的位置:

IndexOf

这可能是不言自明的,但为了避免任何混淆,public class Controller { List m_positions = new List(); public void LoadPositions() { m_positions.Add(new Range(0, 9)); m_positions.Add(new Range(10, 19)); m_positions.Add(new Range(20, 29)); } public int GetPosition (int signal) { Range range = m_positions.Single(a => IsBetween(signal, a.Min, a.Max)); return m_positions.IndexOf(range); } private static bool IsBetween (int target, int min, int max) { return min = target; } }类可能是这样的:

Range

答案 7 :(得分:0)

如果信号范围与位置之间存在直接关联,则使用@agileguy建议的内容。

如果你的位置在信号强度上非线性分布,那么一种方法是:

class SignalStrengthPositionMapper
{
    private static readonly int[] signalStrength = { Int32.MinValue, 0, 5, 11, 15, 20, 27, 35 };
    public static int GetPosition(int strength)
    {
        return StrengthSearch(0, signalStrength.Length, strength);
    }

    // modified binary search
    private static int StrengthSearch(int start, int end, int strength)
    {
        int mid = 0;
        while (start <= end)
        {
            mid = (start + end) / 2;

            if (strength >= signalStrength[mid])         // lower bound check
            {
                start = mid + 1;
                if (strength < signalStrength[start])    // upper bound check
                    return mid;
            }
            else if (strength < signalStrength[mid])     // upper bound check
            {
                end = mid - 1;
                if (strength >= signalStrength[end])     // lower bound check
                    return mid;
            }
        }
        return 0;
    }
}

答案 8 :(得分:-1)

尝试使用泛型:

Dictionary<int,int>  lookup = new Dictionary<int,int>();
lookup.Add(0,1);
lookup.Add(1,1);
lookup.Add(2,1);
lookup.Add(3,1);
...
lookup.Add(9,1);
lookup.Add(10,2);
lookup.Add(11,2);

然后,lookup [22]将返回值3.我建议使用一组循环来创建“范围”。使用此方法,您可以保证O(1)访问时间。