首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用std::find查找一个元素的所有位置?

如何使用std::find查找一个元素的所有位置?
EN

Stack Overflow用户
提问于 2017-03-18 15:58:56
回答 2查看 3K关注 0票数 1

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

我简单地使用了std::find,但是我只能返回第一个位置。

代码语言:javascript
复制
#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分呢?

EN

回答 2

Stack Overflow用户

发布于 2017-03-18 18:08:34

我简单地使用了std::find,但是我只能返回第一个位置。

因为您总是从容器的开头开始搜索。

但是std::find可以搜索任何范围,而不仅仅是一个完整的容器;因此,只需从上一个停止的位置开始每个新的搜索即可。

下面是一个基于您现有代码的示例:

代码语言:javascript
复制
#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是每次搜索开始的迭代器。最初是循环继续,只要向量还没有到达向量为空( end(vec).
  • If ),然后循环永远不会在all.
  • std::find处进入返回迭代器找到的元素或没有找到的元素,然后循环将结束,因为begin(vec) == end(vec)将是end(vec).
  • If It start_it begin(vec) == end(vec),然后,下一次循环迭代将启动std::find search one元素,越过的最后一个结果,因为++start_it; search无论如何,您最终将到达end(vec),您需要显式地记住是否至少有一次搜索成功,因此使用布尔变量。这是因为您需要对未找到任何内容的情况进行特殊处理。如果目标是在从未找到"a"的情况下简单地不打印任何内容,那么您将不需要布尔变量。

一般编码风格的观察:

  • auto是一种很好的方法,可以在不牺牲类型的情况下清楚地说明复杂的类型声明。如果使用std::endl.

,则成员functions.

  • Do的非成员函数beginend <string>不使用std::string,否则代码与平台无关。

  • 使用'\n'而不是your

就我个人而言,我不认为std::find/std::distance-based解决方案在这里是一个非常好的主意。为了代码清晰起见,我可能会使用一个简单的老式for循环,如下所示:

代码语言:javascript
复制
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;
    }
}

请注意,在C++17中,vec.size()可以而且应该被size(vec)取代。

票数 2
EN

Stack Overflow用户

发布于 2017-03-18 16:10:45

下面的代码适用于我:

编辑:对不起,没有仔细阅读问题。;)

编辑:谢谢你的反馈,这是警告-删除了我的代码!

代码语言:javascript
复制
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;
  }
}
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42871932

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档