2013-09-24 88 views
4

我如何找到給定字符串在一行中出現的第n個索引?我需要這個從該索引獲取子字符串。這是可能的通過任何函數在c + +?第n個字符串的索引

回答

9

有在助推find_nth模板函數: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; 
} 
+0

這個答案會給出最後一次出現,即25次。我可以知道如何檢索真正的第二個索引。 – huahsin68

+2

@ huahsin68:該索引是基於零的,因爲它在find_nth文檔中陳述。只需用1找到第二個發生。 –

5

您可以使用下面的函數

#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 = res++; 
    } 
    return res - haystack; 
} 

返回-1,如果它不能找到n次出現。

+0

line「res = res ++;」似乎什麼都不做,會改變它只是「res ++;」 – Streamsoup

1

這個模板函數應該把工作做好

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); 
} 

使用

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 
+0

我可否知道您使用的是哪種版本的增強版? – huahsin68

0

我真的很喜歡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; 
} 
3

這樣做只使用的std :: string的一個簡單的方法::找到

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); 
} 
+0

這段代碼不能很好地處理髮現特定事件的情況。就我而言,它返回了一個不合理的數字。喜歡代碼的簡單性和使用'size_t'。 –

+0

我認爲這個大數字是'string :: npos'。如果沒有找到匹配,函數應該返回'string :: npos',就像'string :: find'一樣。 – rmorarka

+0

這很有道理。然後我會自己處理'string :: npos'。感謝代碼片段! –

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; 
} 
相關問題