它刚刚意识到这段代码只做了一种“设置等效性”检查(现在我看到你确实这么说,我真是个糟糕的读者!)。这可以更简单地实现
template <class T>
static bool compareVectors(vector<T> a, vector<T> b)
{
std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end());
return (a == b);
}
您需要包含标题algorithm
。
如果您的向量始终具有相同的大小,您可能希望在方法的开头添加一个断言:
assert(a.size() == b.size());
如果您曾经错误地执行了不等长的此操作,这将有助于调试您的程序。
否则,如果它们的长度不相等,向量就不能相同,所以只需添加
if ( a.size() != b.size() )
{
return false;
}
在排序指令之前。这将为您节省大量时间。
这在技术上的复杂性是O(n*log(n))
因为它主要取决于(通常)具有这种复杂性的排序。这比您的O(n^2)
方法更好,但由于需要副本,可能会更糟。如果您的原始向量可以排序,这无关紧要。
如果您想坚持自己的方法,但要对其进行调整,以下是我对此的看法:
您可以std::find
为此使用:
template <class T>
static bool compareVectors(const vector<T> &a, const vector<T> &b)
{
const size_t n = a.size(); // make it const and unsigned!
std::vector<bool> free(n, true);
for ( size_t i = 0; i < n; ++i )
{
bool matchFound = false;
auto start = b.cbegin();
while ( true )
{
const auto position = std::find(start, b.cend(), a[i]);
if ( position == b.cend() )
{
break; // nothing found
}
const auto index = position - b.cbegin();
if ( free[index] )
{
// free pair found
free[index] = false;
matchFound = true;
break;
}
else
{
start = position + 1; // search in the rest
}
}
if ( !matchFound )
{
return false;
}
}
return true;
}
另一种可能性是更换结构以存储空闲位置。您可以尝试使用std::bitset
或仅将使用的索引存储在向量中,并检查匹配项是否不在该索引向量中。如果这个函数的结果经常是相同的(所以要么大部分是真的,要么大部分是假的),你可以优化你的数据结构来反映这一点。例如,如果结果通常是错误的,我会使用已使用索引的列表,因为可能只需要存储少数索引。
此方法与您的方法具有相同的复杂性。使用 std::find 搜索有时比手动搜索要好。(例如,如果数据被排序并且编译器知道它,这可以是二进制搜索)。