C++ 字符串第 n 次出现的索引

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18972258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:23:31  来源:igfitidea点击:

Index of nth Occurrence of the string

c++string

提问by Mohan

How do I find the index of nth occurrence of the given string in a line? I need this to take a substring from that index. Is that possible through any functions in c++?

如何找到给定字符串在一行中第 n 次出现的索引?我需要它从该索引中获取一个子字符串。这可以通过 C++ 中的任何函数实现吗?

回答by Vladimir Sinenko

There is a find_nthtemplate function in Boost: http://www.boost.org/doc/libs/1_54_0/doc/html/boost/algorithm/find_nth.html

find_nthBoost 中有一个模板函数:http: //www.boost.org/doc/libs/1_54_0/doc/html/boost/algorithm/find_nth.html

#include <iostream>
#include <boost/algorithm/string/find.hpp>

using namespace std;
using namespace boost;

int main() {

    string a = "The rain in Spain falls mainly on the plain";

    iterator_range<string::iterator> r = find_nth(a, "ain", 2);
    cout << distance(a.begin(), r.begin()) << endl;

    return 0;
}

回答by jv74

For this you can use std::string::findand keep track of the returned position. While doing this you can check to see if the desired string is not found as well and return a -1.

为此,您可以使用std::string::find并跟踪返回的位置。执行此操作时,您可以检查是否也找不到所需的字符串并返回 -1。

#include <string>

int nthOccurrence(const std::string& str, const std::string& findMe, int nth)
{
    size_t  pos = 0;
    int     cnt = 0;

    while( cnt != nth )
    {
        pos+=1;
        pos = str.find(findMe, pos);
        if ( pos == std::string::npos )
            return -1;
        cnt++;
    }
    return pos;
}

回答by rcs

You can use the following function

您可以使用以下功能

#include <string.h>

int strpos(char *haystack, char *needle, int nth)
{
    char *res = haystack;
    for(int i = 1; i <= nth; i++)
    {
        res = strstr(res, needle);
        if (!res)
            return -1;
        else if(i != nth)
            res++;
    }
    return res - haystack;
}

Returns -1 if it can not find the nth occurrence.

如果找不到第 n 个出现,则返回 -1。

回答by rmorarka

A simple way of doing this using just std::string::find

仅使用 std::string::find 执行此操作的简单方法

size_t find_nth(const string& haystack, size_t pos, const string& needle, size_t nth) 
{
    size_t found_pos = haystack.find(needle, pos);
    if(0 == nth || string::npos == found_pos)  return found_pos;
    return find_nth(haystack, found_pos+1, needle, nth-1);
}

回答by yngccc

this template function should get the job done

这个模板函数应该可以完成工作

template<typename Iter>
Iter nth_occurence(Iter first, Iter last,
                   Iter first_, Iter last_,
                   unsigned nth)
{
  Iter it = std::search(first, last, first_, last_);
  if (nth == 0) return it;
  if (it == last) return it;
  return nth_occurence(it + std::distance(first_, last_), last,
                       first_, last_, nth -1);
}

usage

用法

int main()
{
  std::string a = "hello world world world end";
  std::string b = "world";
  auto it1 = nth_occurence(begin(a), end(a), begin(b), end(b), 0);
  auto it2 = nth_occurence(begin(a), end(a), begin(b), end(b), 1);
  auto it3 = nth_occurence(begin(a), end(a), begin(b), end(b), 2);
  auto it4 = nth_occurence(begin(a), end(a), begin(b), end(b), 3);

  std::cout << std::distance(begin(a), it1) << "\n";
  std::cout << std::distance(begin(a), it2) << "\n";
  std::cout << std::distance(begin(a), it3) << "\n";
  std::cout << std::boolalpha << (it4 == end(a)) << "\n";
}

=> 6, 12, 18, true

回答by felleg

I really like rcs's answer which made clever use of pointers. I think that, outside of using the boost library, it is the cleanest way to achieve the result OP wants. However, I had trouble implementing it in certain codes which did not make use of pointers (I'm still a beginner myself), so here is an equivalent answer that does not use either pointers or the boost library.

我真的很喜欢 rcs 的回答,它巧妙地利用了指针。我认为,除了使用 boost 库之外,这是实现 OP 想要的结果的最干净的方法。但是,我无法在某些不使用指针的代码中实现它(我自己仍然是初学者),所以这里有一个不使用指针或 boost 库的等效答案。

int strpos(string haystack, char needle, int nth)
{// Will return position of n-th occurence of a char in a string.
        string read;    // A string that will contain the read part of the haystack
        for (int i=1 ; i<nth+1 ; ++i)
        {
                std::size_t found = haystack.find(needle);
                read += haystack.substr(0,found+1); // the read part of the haystack is stocked in the read string
                haystack.erase(0, found+1);     // remove the read part of the haystack up to the i-th needle
                if (i == nth)
                {
                        return read.size();
                }
        }
        return -1;
}

回答by Max Levy

Another way would be to make use of the last parameter in find_first_of/find_last_ofof std::string. One can do that in a following manner for the last-nthsearch:

另一种方法是使用find_first_of/ find_last_ofof中的最后一个参数std::string。可以通过以下方式进行last-nth搜索:

auto find_last_nth(const std::string& haystack, const std::string& needle, size_t n = 1)
{
    assert(0 != n);

    auto found_last = haystack.length();
    while (true)
    {
        found_last = haystack.find_last_of(needle, found_last - 1);

        if (0 == --n || std::string::npos == found_last)
        {
            return found_last;
        }
    }
}