【问题标题】:Efficient method of finding matching vectors by criteria按标准查找匹配向量的有效方法
【发布时间】:2015-03-26 20:33:34
【问题描述】:

我有一个字典,其中键由 Vector2 定义,我正在尝试执行一个涉及匹配 Y 值的键的函数。 (构建图表)

现在我使用两个 foreach 循环,一个遍历每个条目,第二个查找匹配条件的键。

foreach(KeyValuePair<Vector2, TransportData> entry in transportDictionary)
//for every value in dictionary
{
    Vector2 forpos = entry.Key;

    foreach(KeyValuePair<Vector2,  TransportData> searchEntry in transportDictionary)
    //go through every value in dictionary
    {
        if(searchEntry.Key.y == forpos.y && searchEntry.Key.x != forpos.x)
        //if something is found with matching Y value, at a different X value as to not include itself
        {
        DoSomething(forpos, searchEntry.key);
        //pass the two matched values as arguments
        }

    }
DoSomethingElse(forpos); //(functions need to be run on every entry individually too)

}

它有效,但效率非常高,我预计这本词典有超过一千个条目。对于包含 50 个条目的小型测试集,此操作已经花费了令人无法接受的长时间。

如何优化此操作? (或者我做错了什么?)

如果它有助于查找方法,则此应用程序中每个 Vector2 的 x 和 y 坐标将始终为整数。

--编辑-- 无论如何,我需要在每个条目上运行一个函数,因此没有必要对起始字典进行子集化。

【问题讨论】:

  • 您似乎正在使用== 匹配一些数据。这就是字典的用途。为什么不使用TryGetValue 和其他O(1) 方法?
  • 顺便说一句,对于性能问题Code Review 似乎是更好的地方。

标签: c# search vector


【解决方案1】:

一个想法是首先将您的 transportDictionary 过滤到仅具有至少一个匹配 Key.Y 的那些项目,然后只处理一个键列表(因为这就是您似乎需要的全部)。

然后您还可以将第二个 foreach 更改为仅与具有 Y 匹配的键进行比较,这样您就不会遍历每个循环中的所有键:

最后,您还可以随时删除刚刚处理的所有项目,这样您就不会多次迭代它们(当然,我不知道 DoSomething() 做了什么...如果您需要多次迭代匹配项然后这将不起作用):

List<Vector2> allKeysThatHaveAMatch = transportDictionary.Where(current =>
    transportDictionary.Count(other => current.Key.Y == other.Key.Y) > 1)
    .Select(item => item.Key)
    .ToList();

while (allKeysThatHaveAMatch.Any())
{
    // Get the first key
    var currentKey = allKeysThatHaveAMatch.First();

    // Get all matching keys
    var matchingKeys = allKeysThatHaveAMatch
        .Skip(1)
        .Where(candidateKey => candidateKey.Y == currentKey.Y)
        .Select(match => match)
        .ToList();

    // Do Something with each match
    foreach (var matchingKey in matchingKeys)
    {
        DoSomething(currentKey, matchingKey);
    }

    // Remove the key we just processed
    allKeysThatHaveAMatch.Remove(currentKey);
}

【讨论】:

  • 我以前从未使用过 Linq(一周前才开始编程),我花了一段时间才理解语法,但我做到了。但是我做了一些基准测试,它实际上比我原来的蛮力方法要慢一些。使用非常大的数据集可能会更快(我只测试了多达 200 个条目),但我有另一个想法,涉及创建一个反向字典并在其中查找匹配值。我非常感谢您如何格式化和命名您的建议代码,使其更容易理解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-25
  • 1970-01-01
  • 1970-01-01
  • 2015-07-15
  • 1970-01-01
  • 2011-06-11
相关资源
最近更新 更多