我的代码是:
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
用于排序目的。)
我不是故意将当前的实现包含在社区中,而不仅仅是分析我的代码,而是提出新的解决方案。
答案 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)set
的O(log(n)),vector
的O(n)set
中完成,对vector
采用O(n * log(n))然后,正如您所看到的,如果您不经常修改链但经常检查链,std::set
是一个很好的解决方案。