【发布时间】:2017-01-10 11:17:32
【问题描述】:
有一个多对多关系列表(N = 1000000)。我需要尽快确定列表中的关系索引并枚举特定项目的所有关系。
我知道可以为 from/to 创建查找表(时间 O(1)),但它的大小太大(N*N)。而且我知道我可以使用二进制搜索(时间为 O(log(N))),但它仍然很慢。还有其他解决方案吗?
C#代码:
public class Relation
{
public int From;
public int To;
}
public class Table
{
public List<Relation> Relations { get; } = new List<Relation>();
public void Add(int from, int to)
{
if (IndexOf(from, to) == -1)
{
Relations.Add(new Relation() { From = from, To = to });
}
}
public int IndexOf(int from, int to)
{
// this algorithm make O(N) comparisons, but I need O(1)
for (int i = 0; i < Relations.Count; i++)
{
if (Relations[i].From == from && Relations[i].To == to) return i;
}
return -1;
}
public IEnumerable<int> FromsOf(int to)
{
// this algorithm make O(N) comparisons, but I need O(1)
for (int i = 0; i < Relations.Count; i++)
{
if (Relations[i].To == to) yield return Relations[i].From;
}
}
}
class Program
{
static void Main(string[] args)
{
Random r = new Random();
Table t = new Table();
int N = 1000000;
for (int i = 0; i < N; i++) t.Add(r.Next(N), r.Next(N));
DateTime t1 = DateTime.Now;
for (int i = 0; i < N; i++)
{
if (t.IndexOf(r.Next(N), r.Next(N)) != -1)
{
// do something
}
}
DateTime t2 = DateTime.Now;
for (int i = 0; i < N; i++)
{
foreach (int j in t.FromsOf(r.Next(N)))
{
// do something
}
}
DateTime t3 = DateTime.Now;
Console.WriteLine($"IndexOf speed = {(t2 - t1).TotalMilliseconds / N}ms");
Console.WriteLine($"FromsOf speed = {(t3 - t2).TotalMilliseconds / N}ms");
}
}
【问题讨论】:
-
使用带有 From 键和 To 键的 2 个字典。 1000000 ~ 3.8Mb