是否可以使用具有一系列值的哈希表?

时间:2014-02-21 12:48:19

标签: c# wpf hash hashtable

情况:

  1. 我有一组X(例如10,000)捕获的屏幕坐标。
  2. 屏幕上显示的是虚拟键盘。这将呈现为相邻矩形控件的行(在本例中为边框控件)。
  3. 如果我执行标准命中测试,我想将每个屏幕坐标转换为它会击中的键,即哪个键是坐标。
  4. 这需要尽可能高效地完成。
  5. 可能的解决方案:

    1. 生成一组包含每个键的屏幕坐标(LeftX,RightX,TopY,BottomY)的键位置,如果屏幕键盘被移动/调整大小,则更新此位置。
    2. 遍历我捕获的屏幕坐标并查找与之相关的密钥。
    3. 问题:

      忽略并行执行循环的潜在收益,我想了解用于获取屏幕坐标并根据存储的关键位置集执行匹配键的查找的最佳结构和查找技术。

      知道键盘上的键是水平和垂直相邻的,我可以使用它来优化查找,例如创建键行的哈希表,并使用屏幕坐标的Y组件返回null(坐标不在键盘上)或另一个表示该行中键的哈希表。然后我可以使用屏幕坐标的X组件进行类似的查找。

      请记住,键通常不会对齐列,所以在查找行中的键之前,我必须查找一行,而不是将屏幕坐标的X组件与列匹配,然后查找关键在那一栏。

      我怀疑使用标准WPF命中测试会非常低效,因为当我只关心单个图层时,它会在坐标下测试所有可能的视觉效果。

      感谢您提供给我的任何帮助。这可能是微不足道的,但我不熟悉基于一系列值的哈希方法

1 个答案:

答案 0 :(得分:1)

如果你使用索引(因为它们的工作速度比其他任何东西都快),那么最快的命中测试是可能的。

为键盘的每个键分配一个整数(例如,扫描码)。然后创建一个像这样的点图

int[] map = new int[ymax * xmax]; // 1920*1200 = 2.304.000 (sizeof(int) * 2.3 Mb)

虽然它占用了大量内存,但您可以使用它来映射其他内容。也可以首先索引键(假设有~100个键,你可以使用byte数组来保存键索引,但是你需要一个从索引到键的附加映射)。

地图告诉谁是像素的所有者。它可以是0(无人)或某人(键扫描码/键索引/对象索引)。

命中测试和

一样难
return map[x + y * xmax];

但在您的情况下,我建议将关键边界表示为Rectangle。迭代超过100个密钥(在最差密钥中)和Rectangle.Contains(point)需要时间,但解决方案可能足够好(并且使用很少的内存)。