簡體   English   中英

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類,這將是完美的,但我正在使用C ++ 14。

您可以通過組合API來限制原始字符串中的搜索長度,並進行額外檢查以查看最終結果是否位於substr_beg之前,從而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如果它出現在substring的初始字符之前,則拒絕一個答案。

演示。

來自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的“有用”方法。

另一個選擇是使用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";
}

使用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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM