2017-03-18 287 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

相关问题