2017-03-18 288 views
0

我正在使用以下代碼在std::stringstd::vector中查找字符串。但是如何返回特定元素的所有位置?如何使用std :: find查找元素的所有位置?

我只是使用std::find,但我只能返回第一個位置。

#include <iostream> 
#include <algorithm> 
#include <vector> 

using namespace std; 

int main() { 
    vector<string> vec; 
    vector<string>::iterator it; 

    vec.push_back("a"); 
    vec.push_back("i"); 
    vec.push_back("g"); 
    vec.push_back("h"); 
    vec.push_back("l"); 
    vec.push_back("a"); 
    vec.push_back("n"); 
    vec.push_back("d"); 
    vec.push_back("e"); 
    vec.push_back("r"); 

    it=find(vec.begin(),vec.end(),"a"); 
    int pos = distance(vec.begin(), it); 

    if(it!=vec.end()){ 
     cout<<"FOUND AT : "<<pos<<endl; 
    } 
    else{ 
     cout<<"NOT FOUND"<<endl; 
    } 
    return 0; 
} 

我只能得到0,我怎麼能得到5呢?

+5

[查找向量中所有元素出現的索引]的可能副本(http://stackoverflow.com/questions/25846235/finding-the-indexes-of-all-occurrences-of-an-element -in-a-vector) –

+2

std :: find(it + 1,vec.end(),「a」)? – stijn

回答

-2

此代碼適用於我:

編輯:抱歉沒有仔細閱讀問題。 ;)

編輯:感謝您的反饋,這是警告 - 刪除我的代碼!

auto begin = vec.begin(); 
unsigned int pos = 0; 
while (true) 
{ 
    auto result = find(begin, vec.end(), "a"); 
    if (result == vec.end())  break; 
    else 
    { 
    if(result == begin) printf("pos: %d\n", pos); 
    ++begin; 
    ++pos; 
    } 
} 
+0

你必須解釋你的代碼,而不是複製粘貼它! –

+0

這並不回答問題。 OP想要得到**''a「'元素的位置,你的代碼只能檢測到一個。 –

+0

你是對的,那麼將修改我的代碼。 – sailfish009

2

我簡單地使用std::find,但我只能回到第一的位置。

因爲您總是在容器的開始處開始搜索。

std::find可以搜索任何範圍,不只是一個完整的容器;相反,只需開始每個新搜索,其中最後一個停止

這是基於現有代碼的例子:在這個特定的程序

#include <iostream> 
#include <algorithm> 
#include <vector> 
#include <string> 

int main() { 
    std::vector<std::string> vec; 

    vec.push_back("a"); 
    vec.push_back("i"); 
    vec.push_back("g"); 
    vec.push_back("h"); 
    vec.push_back("l"); 
    vec.push_back("a"); 
    vec.push_back("n"); 
    vec.push_back("d"); 
    vec.push_back("e"); 
    vec.push_back("r"); 

    bool found_at_least_once = false; 
    auto start_it = begin(vec); 
    while (start_it != end(vec)) { 
     start_it = std::find(start_it, end(vec), "a"); 
     if (start_it != end(vec)) { 
      auto const pos = std::distance(begin(vec), start_it); 
      std::cout << "FOUND AT : " << pos << '\n'; 
      ++start_it; 
      found_at_least_once = true; 
     } 
    } 

    if (!found_at_least_once) { 
     std::cout << "NOT FOUND" << '\n'; 
    } 
} 

觀察:

  • start_it是,每一個搜索開始的迭代器。它最初是begin(vec)
  • 只要start_it未到達end(vec),循環就會繼續。
  • 如果矢量爲空(begin(vec) == end(vec)),則根本不輸入循環。
  • std::find返回迭代器找到的元素或end(vec)
  • 如果找不到元素,則循環將結束,因爲start_it將是end(vec)
  • 如果找到了,則由於++start_it;行,因此下一個循環迭代將開始std::find搜索一個元素超過最後的結果。
  • 因爲無論如何你最終會到達end(vec),所以你需要明確地記住至少有一次搜索是否成功,因此是布爾變量。那是因爲當你沒有發現任何東西時你需要特殊的處理。如果目標不是簡單地打印任何東西,如果從未找到"a",那麼您將不需要布爾變量。

通用編碼風格的意見:

  • auto是消除拼寫出複雜的類型聲明不犧牲類型安全需要一個偉大的方式。
  • 首選成員函數非成員函數beginend
  • 請勿使用using namespace std;
  • 如果您使用std::string,請包括<string>,否則您的代碼根本無法取決於平臺。
  • 使用'\n'而不是std::endl

就個人而言,我不認爲一個std::find/std::distance爲基礎的解決方案是在這裏一個非常好的主意。對於代碼清晰起見,我可能會使用一個普通的老for循環是這樣的:

bool found_at_least_once = false; 
for (std::vector<std::string>::size_type pos = 0; pos < vec.size(); ++pos) { 
    if (vec[pos] == "a") { 
     std::cout << "FOUND AT : " << pos << '\n'; 
     found_at_least_once = true; 
    } 
} 

注意vec.size()可以也應該以size(vec)在C++ 17所代替。

+0

想對你的第一個版本發表評論,do {} while()看起來有點奇怪,不需要,但是你已經修復了它:] – stijn

相關問題