我目前正在尝试创建一个根据信号强度估算位置的程序。信号强度值是一个int,然后我需要一个带范围的查找字典。
所以我会有类似的东西:
Signal Strenth Position
0-9 1
10-19 2
20-29 3
然后我想查看信号强度所涉及的位置,例如15与位置2有关。
我知道我可以加载一些if语句但是有一种很好的方法可以使用某种查找字典吗?
答案 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)访问时间。