這裏是你可以嘗試的解決方案。但是它假定一些要點:
- 沒有範圍重疊
- 當你請求一個數字,它是一個有效的範圍內(沒有錯誤檢查)
從你說的話,這個人是O(N),但你可以用我很小的努力使它成爲O(log(N))。
想法是,一個類將處理範圍事物,它將基本上將給定的任何值轉換爲其範圍的下邊界。這樣你的Hashtable(這裏是一個字典)包含低邊界作爲鍵。
public class Range
{
//We store all the ranges we have
private static List<int> ranges = new List<int>();
public int value { get; set; }
public static void CreateRange(int RangeStart, int RangeStop)
{
ranges.Add(RangeStart);
ranges.Sort();
}
public Range(int value)
{
int previous = ranges[0];
//Here we will find the range and give it the low boundary
//This is a very simple foreach loop but you can make it better
foreach (int item in ranges)
{
if (item > value)
{
break;
}
previous = item;
}
this.value = previous;
}
public override int GetHashCode()
{
return value;
}
}
這裏是測試它。
class Program
{
static void Main(string[] args)
{
Dictionary<int, int> myRangedDic = new Dictionary<int,int>();
Range.CreateRange(10, 20);
Range.CreateRange(50, 100);
myRangedDic.Add(new Range(15).value, 1000);
myRangedDic.Add(new Range(75).value, 5000);
Console.WriteLine("searching for 16 : {0}", myRangedDic[new Range(16).value].ToString());
Console.WriteLine("searching for 64 : {0}", myRangedDic[new Range(64).value].ToString());
Console.ReadLine();
}
}
我不相信你真的可以去下面爲O(log(N)),因爲沒有方法可以讓你馬上知道在哪個範圍內的數字是,你必須始終以較低的進行比較(或上限)。
如果你有預定的範圍,那本來會容易些。即如果你的範圍是每百個,通過計算它的模100很容易找到任何數字的正確範圍,但是在這裏我們不能假設,所以我們必須檢查。
下井的log(n)與此解決方案,只需更換一個循環,將着眼於陣列的中間的foreach,那麼它在每兩個迭代分裂...
爲什麼不直接使用HashSet與匹配所需邏輯的比較器? –
但是HashSet沒有密鑰。 – Paparazzi
是否有任何關於範圍的知識,或者它們可以是任何東西? – Chris