使用Xcode分发的LLVM libc ++(对于C ++ 11)的string :: find方法实现了什么算法(及其复杂性)?我找不到任何关于它的文档,并且跟随库标题并不是很容易。有人可以帮忙吗?
答案 0 :(得分:5)
这是他们的basic_string
' find
(只发布了一次重载):
template<class _CharT, class _Traits, class _Allocator>
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
size_type __pos,
size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
return _VSTD::__str_find<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
可以看出,这只是派遣到辅助函数__str_find
,它执行一些简单的检查,然后调用<algorithm>
中的辅助函数__search
:
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_find(const _CharT *__p, _SizeT __sz,
const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
{
if (__pos > __sz || __sz - __pos < __n)
return __npos;
if (__n == 0)
return __pos;
const _CharT* __r =
_VSTD::__search(__p + __pos, __p + __sz,
__s, __s + __n, _Traits::eq,
random_access_iterator_tag(), random_access_iterator_tag());
if (__r == __p + __sz)
return __npos;
return static_cast<_SizeT>(__r - __p);
}
值得注意的是__search
也是std::search
调用的函数:
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
inline _LIBCPP_INLINE_VISIBILITY
_ForwardIterator1
search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
{
return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type>
(__first1, __last1, __first2, __last2, __pred,
typename std::iterator_traits<_ForwardIterator1>::iterator_category(),
typename std::iterator_traits<_ForwardIterator2>::iterator_category());
}
__search
本身的实现是相当标准的,如果!_LIBCPP_UNROLL_LOOPS
为零,则手动展开循环。您可以在上面链接的<algorithm>
标题中找到它。
答案 1 :(得分:0)
根据cplusplus.com:
http://www.cplusplus.com/reference/string/string/find/
复杂性: 未指定,但通常长度为线性() - pos乘以匹配的序列长度(最坏情况)。
我认为在libcxx(c ++ lib llvm链接)中实现了字符串匹配的特殊算法。 如果您在libcxx SVN存储库中搜索&#34; find&#34;的源代码,则只能获得debug.cpp的提示。
因此复杂性是天真搜索算法的复杂性。如果您需要像Knut-Morris-Pratt等特殊算法(https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm),请查看boost实现。