#include <iostream>
#include <chrono>
#include <string>
using namespace std::chrono;
int main(int arc, char* argv[]) {
const std::string password = "a";
int correct = 1;
auto start = high_resolution_clock::now();
if(password != argv[1])
correct = 0;
auto end = high_resolution_clock::now();
auto elapsed = duration_cast<nanoseconds> (end-start).count();
std::cout << "time: " << elapsed << "\n";
return correct;
}
[“ a” ==“ b”和“ a” ==“ bbbbbbbbbbbbb ...”的比较平均要长50%以上(长度〜250)。
为什么会这样?看到第一个字符不相等(或者字符串的长度不相等)后,字符串比较功能是否应该立即中断?
[许多参考文献还提到,字符串比较在两个输入字符串的长度上都是线性复杂度(例如https://en.cppreference.com/w/cpp/string/basic_string/operator_cmp)。我不明白为什么会这样。非常感谢您的帮助。
字符串== operator
依赖于compare()
方法。查看我的TDMGCC上的可用实现,我发现了这一点:
// This is the overloaded one called when you compare to argv[1]
template<typename _CharT, typename _Traits, typename _Alloc>
int
basic_string<_CharT, _Traits, _Alloc>::
compare(const _CharT* __s) const
{
__glibcxx_requires_string(__s);
const size_type __size = this->size();
const size_type __osize = traits_type::length(__s);
const size_type __len = std::min(__size, __osize);
int __r = traits_type::compare(_M_data(), __s, __len);
if (!__r)
__r = _S_compare(__size, __osize);
return __r;
}
如您所见,在比较长度之前,它首先将其称为traits_type::compare()
,它基本上是memcmp()
:
static int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{ return __builtin_memcmp(__s1, __s2, __n); }
因此,如果我没记错的话,比较将是您提到的线性时间。
这里首先要注意的是operator==()
内部使用compare()
方法,如here所述。
如here和here所述,compare()
方法的许多实现依赖于memcmp
。 (或某些等效函数),您可以在this C实现中看到memcmp
使用的算法具有线性时间复杂度。该特定实现在下面给出。
int
memcmp (const PTR str1, const PTR str2, size_t count)
{
register const unsigned char *s1 = (const unsigned char*)str1;
register const unsigned char *s2 = (const unsigned char*)str2;
while (count-- > 0)
{
if (*s1++ != *s2++)
return s1[-1] < s2[-1] ? -1 : 1;
}
return 0;
}
由于compare()
方法的这种内部实现以及所涉及的优化,您可能需要更大尺寸的字符串,才能观察该方法执行所花费的时间中的线性趋势。