在矢量矢量中找到矢量的最快方法

时间:2015-04-24 06:04:11

标签: c++ vector stl stdvector

我的代码是:

struct TileIdx { int mRow; int mCol; };

typedef std::vector<TileIdx> TileChain;

bool IsChainInChains(const TileChain& chain, const std::vector<TileChain>& chainArray);

分析器显示IsChainInChains是我的代码的瓶颈 我需要以最快的方式来实现这个功能 我们可以假设,chainArray已经排序(哪种方式?取决于你) 我们也可以假设mRow和mCol不会超过100(即mRow * 100 + mCol是有效的int用于排序目的。)
我不是故意将当前的实现包含在社区中,而不仅仅是分析我的代码,而是提出新的解决方案。

2 个答案:

答案 0 :(得分:3)

在没有太多有用信息的情况下,我建议使用二进制搜索。为此,请使用标准库函数std::lower_bound

auto it = std::lower_bound(begin(chainArray), end(chainArray), chain, comp);

其中comp是用于排序chainArray的谓词,并且是严格弱排序

请注意,std::vector有一个operator<,可以对其元素进行字典比较。如果使用三个参数调用,std::lower_bound将使用它。因此,如果您将bool operator<(TileIdx, TileIdx)实现为严格的弱排序,则可以省略comp的使用:

bool operator<(TileIdx rhs, TileIdx lhs) { .... }

std::sort(begin(chainArray), end(chainArray));

....

auto it = std::lower_bound(begin(chainArray), end(chainArray), chain);

答案 1 :(得分:1)

你真的需要矢量矢量吗?如果您对数据的其他操作可能较慢,则可以使用一组向量。看到这个小例子:

#include <set>
#include <vector>

struct TileIdx { int mRow; int mCol; };

typedef std::vector<TileIdx> TileChain;

bool operator < (const TileChain& t1, const TileChain& t2)
{
  if(t1.size() < t2.size())
    return true;
  if(t1.size() > t2.size())
    return false;
  for(unsigned long int i = 0; i < t1.size(); ++i)
  {
    if(t1[i].mRow < t2[i].mRow)
      return true;
    if(t1[i].mRow > t2[i].mRow)
      return false;
  }
  return false;
}

bool IsChainInChains(const TileChain& chain, const std::set<TileChain>& chains)
{
  return chains.count(chain) > 0;
}

然后,您必须根据目标选择容器。为了您的信息,这些操作所需的时间是:

  • 在链中插入一个新链,取set的O(log(n)),vector的O(1)
  • 在Chains中找到一个链为set的O(log(n)),vector的O(n)
  • 对链中的链进行排序已在set中完成,对vector采用O(n * log(n))

然后,正如您所看到的,如果您不经常修改链但经常检查链,std::set是一个很好的解决方案。