2012-11-22 254 views
2

好的,所以我一直在尋找一種算法,可以幫助我在子字符串中找到一個字符串。 我之前使用的代碼來自similar question,但它沒有這樣做。在字符串C++中查找子字符串(在「hello」中查找「el」)

// might not be exposed publicly, but could be 
int index_of(string const& haystack, int haystack_pos, string const& needle) { 
    // would normally use string const& for all the string parameters in this 
    // answer, but I've mostly stuck to the prototype you already have 

    // shorter local name, keep parameter name the same for interface clarity 
    int& h = haystack_pos; 

    // preconditions: 
    assert(0 <= h && h <= haystack.length()); 

    if (needle.empty()) return h; 
    if (h == haystack.length()) return -1; 
    if (haystack.compare(h, needle.length(), needle) == 0) { 
    return h; 
    } 
    return index_of(haystack, h+1, needle); 
} 

int index_of(string haystack, string needle) { 
    // sets up initial values or the "context" for the common case 
    return index_of(haystack, 0, needle); 
} 

這不會返回字符串「hello」上的「el」開始索引,我無法弄清楚。

編輯: OK,讓我告訴你更多的包括一些現實生活中的例子代碼: 我試圖分析一個字符串,它是一個文件我想在我的文件系統來排序的路徑。 輸入例如是這樣的:

輸入:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE。 mkv

當我嘗試通過檢測SxxExx的存在來解析此字符串以獲取其名稱時,我查找「s0」,「S0」等(我知道這不是我剛纔嘗試的最佳實現看看它是否工作,然後看看代碼)。所以,當我使用該輸入,我所得到的輸出是:

input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv 

aux: 0p.HDTV.x264-IMMERSE.mkv 

input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv 

aux: 1.720p.HDTV.x264-IMMERSE.mkv 

input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv 

aux: 264-IMMERSE.mkv 

預期輸出AUX:S04E01.720p.HDTV.x264-IMMERSE.mkv

因此,大家可以看到,它只是看對於字符串中的任何字符和停止,這也佔多個有效的「找到」應該只是一個。

在那裏我試圖用這個是全碼:

bool StringWorker::isSeries(size_t &i) { 

    size_t found1, found2, found3, found4, found5, found6; 
    found1 = input->find_last_of("S0"); //tried several find functions including the 
    found2 = input->find_last_of("S1"); //index_of() mentioned above in the post 
    found3 = input->find_last_of("S2"); 
    found4 = input->find_last_of("s0"); 
    found5 = input->find_last_of("s1"); 
    found6 = input->find_last_of("s2"); 

    if (found1 != string::npos) { 
     if (input->size() - found1 > 6) { 
      string aux = input->substr(found1, input->size()); 
      cout << "input:" << *input << endl; 
      cout << "aux: " << aux << endl; 
      if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2)) 
        && isalpha(aux.at(3)) && isdigit(aux.at(4)) 
        && isdigit(aux.at(5))) { 
       i = found1; 
       return true; 
      } 
     } 
    } 
    if (found2 != string::npos) { 
     if (input->size() - found2 > 6) { 
      string aux = input->substr(found2, input->size()); 
      cout << "input:" << *input << endl; 
      cout << "aux: " << aux << endl; 
      if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2)) 
        && isalpha(aux.at(3)) && isdigit(aux.at(4)) 
        && isdigit(aux.at(5))) { 
       i = found2; 
       return true; 
      } 
     } 
    } 

    if (found3 != string::npos) { 
     if (input->size() - found3 > 6) { 
      string aux = input->substr(found3, input->size()); 
      cout << "input:" << *input << endl; 
      cout << "aux: " << aux << endl; 
      if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2)) 
        && isalpha(aux.at(3)) && isdigit(aux.at(4)) 
        && isdigit(aux.at(5))) { 
       i = found3; 
       return true; 
      } 
     } 

    } 
    if (found4 != string::npos) { 
     if (input->size() - found4 > 6) { 
      string aux = input->substr(found4, input->size()); 
      cout << "input:" << *input << endl; 
      cout << "aux: " << aux << endl; 
      if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2)) 
        && isalpha(aux.at(3)) && isdigit(aux.at(4)) 
        && isdigit(aux.at(5))) { 
       i = found4; 
       return true; 
      } 
     } 

    } 
    if (found5 != string::npos) { 
     if (input->size() - found5 > 6) { 
      string aux = input->substr(found5, input->size()); 
      cout << "input:" << *input << endl; 
      cout << "aux: " << aux << endl; 
      if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2)) 
        && isalpha(aux.at(3)) && isdigit(aux.at(4)) 
        && isdigit(aux.at(5))) { 
       i = found5; 
       return true; 
      } 
     } 

    } 
    if (found6 != string::npos) { 
     if (input->size() - found6 > 6) { 
      string aux = input->substr(found6, input->size()); 
      cout << "input:" << *input << endl; 
      cout << "aux: " << aux << endl; 
      if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2)) 
        && isalpha(aux.at(3)) && isdigit(aux.at(4)) 
        && isdigit(aux.at(5))) { 
       i = found6; 
       return true; 
      } 
     } 

    } 

    return false; 

} 

你能看到這裏有什麼問題?

+7

['std :: string :: find'](http://en.cppreference.com/w/cpp/string/basic_string/find)有什麼問題? –

+1

'std :: search'有什麼問題? –

+0

適合我。您必須錯誤地使用該功能。發佈完整的程序。 – john

回答

6

爲什麼不使用std::stringfind()方法 - >link

+0

因爲std :: string的find()方法在傳遞一個字符串「el」時將返回「e」的第一個匹配項,即使沒有後跟「l」也會導致錯誤。 – JackTakahashi

+0

@JackTakahashi我不這麼認爲 –

+1

看看我編輯原始帖子的例子。你會明白我的意思。 – JackTakahashi

3

此代碼返回通過index = sub_str.find("el")指數:

#include <iostream> 
#include <string> 
using namespace std; 

int main() 
{ 
    string sub_str="abc def ghi jk lmnop hello"; 

    string sub_str2; 
    size_t index; 


    index = sub_str.find("el");  
    sub_str2 = sub_str.substr (index); 

    cout<<"index = "<<index<<"\n"; 
    cout<<sub_str2<<"\n"; 

    return 0; 
} 
0

用於查找字符串中的子串和它的索引,你可以嘗試了這一點 -

int find_sub(const std::string& mstring,sub) 
{ 
    int lensub=sub.length(),len=mstring.length(),f=0,pos; 
    std::string b=""; 
    for(int i=0;i<len-lensub;i++) 
    { 
    for(int j=i,k=0;j<i+lensub;j++,k++) 
     b[k]=mstring[j]; 
    if(b.compare(sub)==0) 
    { 
     f=1; 
     pos=i; 
     break; 
    } 
    } 
    if(f==1) 
    cout<<"substring found at: "<<pos+1; 
    else 
    cout<<"substring not found!"; 
    return f; 
} 

您還檢查字符串出現了多少次通過刪除break;並每次增加f的值。也可以通過將pos轉換爲數組來獲得索引。

+0

OP使用'std :: string',問題標記爲'C++'。如果你真的想幫忙,試着去理解爲什麼OP代碼是錯誤的。 – manuell

+0

也是三年前的問題 –

+0

@manuell我認爲我的代碼可以轉換爲可用於'std :: string',無論如何我編輯它。我使用數組是因爲我不太熟悉std :: string。 「你是什麼意思」標籤爲「C++'」?我其實寫了一個C++代碼。 – TubbyStubby