C ++查找子字符串中字符串的最后一次出现
C++ Find last ocurrence of a string inside a substring
我需要一种方法来帮助我在另一个子字符串中找到一个字符串,或者换句话说,在其他字符串的子范围内找到一个字符串。此外,我需要以相反的顺序找到它,因为我知道我要查找的字符串已关闭到用作 "haystack".
的子字符串的末尾
让我们假设以下代码,其中 rfind_in_substr
是我要求的方法:
std::string sample("An example with the example word example trice");
// substring "ample with the example wo"
std::size_t substr_beg = 5;
std::size_t substr_size = 24;
// (1)
std::size_t pos = rfind_in_substr(sample, substr_beg,
substr_size, "example");
// pos == 20, because its the index of the start of the second
// "example" word inside the main string.
当然,第 (1) 行可以替换为:
std::size_t pos = substr_beg + sample.substr
(substr_beg, substr_size).rfind("example");
但这意味着子字符串的一个不必要的副本。有什么方法或 C++/boost 方法可以帮助我做到这一点吗?
我正在查看 boost::algorithm::string
图书馆,但我什么也没找到(我已经理解)。我知道 C++17 有 std::string_view
class,那将是完美的,但我使用的是 C++14。
您可以通过组合 API 来找到答案,该 API 按长度限制在原始字符串中搜索,并额外检查最终结果是否先于 substr_beg
:
std::size_t rfind_in_substr(
const std::string& str
, const std::size_t from
, const std::size_t len
, const std::string& sub
) {
std::size_t res = str.rfind(sub, from+len-sub.size());
return res != string::npos && res >= from ? res : string::npos;
}
from+len-sub.size()
计算子字符串可以开始的最后位置。
res >= from
如果答案出现在子字符串的初始字符之前,则拒绝答案。
使用 std::find_end
可以有效地解决问题,而无需使用过多的资源,但我希望有任何方法已经解决了这个问题:
#include <iostream>
#include <string>
#include <algorithm>
std::size_t rfind_in_substr(std::string const& str, std::size_t from,
std::size_t len, std::string const& s)
{
auto sub_beg = str.begin() + from;
auto sub_end = sub_beg + len;
auto found_it = std::find_end(sub_beg, sub_end, s.begin(), s.end());
if (found_it == sub_end)
return str.npos;
else
return found_it - str.begin();
}
int main()
{
std::string sample("An example with the example word example trice");
// substring "ample with the example w"
std::size_t substr_beg = 5;
std::size_t substr_size = 24;
std::size_t pos = rfind_in_substr(sample, substr_beg,
substr_size, "example");
std::cout << pos << std::endl; // Prints 20
}
来自Boost.StringAlgo:
#include <boost/algorithm/string/find.hpp>
auto haystack = boost::make_iterator_range(str.begin() + from, str.begin() + from + len);
auto found = boost::algorithm::find_last(haystack, needle);
现在,如果您需要将它与来自 std::string
的其他成员函数一起使用,则需要执行额外的步骤将结果范围转换为索引,例如 ,但如果您不是t,然后简单地使用范围接口并避免使用 std::string
的 "helpful" 方法。
另一种选择是使用 boost::string_ref
,这是 std::string_view
的基本依据:
#include <iostream>
#include <boost/utility/string_ref.hpp>
std::size_t rfind_in_substr(std::string const& str, std::size_t from,
std::size_t len, std::string const& s)
{
return from + boost::string_ref(str).substr(from, len).rfind(s);
}
int main()
{
std::string sample("An example with the example word example trice");
// substring "ample with the example wo"
std::size_t substr_beg = 5;
std::size_t substr_size = 24;
// (1)
std::size_t pos = rfind_in_substr(sample, substr_beg,
substr_size, "example");
// pos == 20, because its the index of the start of the second
// "example" word inside the main string.
std::cout << pos << "\n";
}
我需要一种方法来帮助我在另一个子字符串中找到一个字符串,或者换句话说,在其他字符串的子范围内找到一个字符串。此外,我需要以相反的顺序找到它,因为我知道我要查找的字符串已关闭到用作 "haystack".
的子字符串的末尾让我们假设以下代码,其中 rfind_in_substr
是我要求的方法:
std::string sample("An example with the example word example trice");
// substring "ample with the example wo"
std::size_t substr_beg = 5;
std::size_t substr_size = 24;
// (1)
std::size_t pos = rfind_in_substr(sample, substr_beg,
substr_size, "example");
// pos == 20, because its the index of the start of the second
// "example" word inside the main string.
当然,第 (1) 行可以替换为:
std::size_t pos = substr_beg + sample.substr
(substr_beg, substr_size).rfind("example");
但这意味着子字符串的一个不必要的副本。有什么方法或 C++/boost 方法可以帮助我做到这一点吗?
我正在查看 boost::algorithm::string
图书馆,但我什么也没找到(我已经理解)。我知道 C++17 有 std::string_view
class,那将是完美的,但我使用的是 C++14。
您可以通过组合 API 来找到答案,该 API 按长度限制在原始字符串中搜索,并额外检查最终结果是否先于 substr_beg
:
std::size_t rfind_in_substr(
const std::string& str
, const std::size_t from
, const std::size_t len
, const std::string& sub
) {
std::size_t res = str.rfind(sub, from+len-sub.size());
return res != string::npos && res >= from ? res : string::npos;
}
from+len-sub.size()
计算子字符串可以开始的最后位置。res >= from
如果答案出现在子字符串的初始字符之前,则拒绝答案。
使用 std::find_end
可以有效地解决问题,而无需使用过多的资源,但我希望有任何方法已经解决了这个问题:
#include <iostream>
#include <string>
#include <algorithm>
std::size_t rfind_in_substr(std::string const& str, std::size_t from,
std::size_t len, std::string const& s)
{
auto sub_beg = str.begin() + from;
auto sub_end = sub_beg + len;
auto found_it = std::find_end(sub_beg, sub_end, s.begin(), s.end());
if (found_it == sub_end)
return str.npos;
else
return found_it - str.begin();
}
int main()
{
std::string sample("An example with the example word example trice");
// substring "ample with the example w"
std::size_t substr_beg = 5;
std::size_t substr_size = 24;
std::size_t pos = rfind_in_substr(sample, substr_beg,
substr_size, "example");
std::cout << pos << std::endl; // Prints 20
}
来自Boost.StringAlgo:
#include <boost/algorithm/string/find.hpp>
auto haystack = boost::make_iterator_range(str.begin() + from, str.begin() + from + len);
auto found = boost::algorithm::find_last(haystack, needle);
现在,如果您需要将它与来自 std::string
的其他成员函数一起使用,则需要执行额外的步骤将结果范围转换为索引,例如 std::string
的 "helpful" 方法。
另一种选择是使用 boost::string_ref
,这是 std::string_view
的基本依据:
#include <iostream>
#include <boost/utility/string_ref.hpp>
std::size_t rfind_in_substr(std::string const& str, std::size_t from,
std::size_t len, std::string const& s)
{
return from + boost::string_ref(str).substr(from, len).rfind(s);
}
int main()
{
std::string sample("An example with the example word example trice");
// substring "ample with the example wo"
std::size_t substr_beg = 5;
std::size_t substr_size = 24;
// (1)
std::size_t pos = rfind_in_substr(sample, substr_beg,
substr_size, "example");
// pos == 20, because its the index of the start of the second
// "example" word inside the main string.
std::cout << pos << "\n";
}