C++ 如何在 std::vector 中找到元素位置?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1425349/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:56:09  来源:igfitidea点击:

How do I find an element position in std::vector?

c++searchstlvector

提问by sharptooth

I need to find an element position in an std::vector to use it for referencing an element in anothervector:

我需要在 std::vector 中找到一个元素位置,以使用它来引用另一个向量中的元素:

int find( const vector<type>& where, int searchParameter )
{
    for( int i = 0; i < where.size(); i++ ) {
       if( conditionMet( where[i], searchParameter ) ) {
           return i;
       }
    }
    return -1;
}
// caller:
const int position = find( firstVector, parameter );
if( position != -1 ) {
    doAction( secondVector[position] );
}

however vector::size()returns size_twhich corresponds to an unsignedintegral type that can't directly store -1. How do I signal that the element is not found in a vector when using size_tinstead of intas an index?

但是vector::size()返回size_t对应于unsigned不能直接存储的整数类型-1。当使用size_t而不是int作为索引时,如何表示在向量中找不到该元素?

采纳答案by Kirill V. Lyadvinsky

You could use std::numeric_limits<size_t>::max()for elements that was not found. It is a valid value, but it is impossible to create container with such max index. If std::vectorhas size equal to std::numeric_limits<size_t>::max(), then maximum allowed index will be (std::numeric_limits<size_t>::max()-1), since elements counted from 0.

您可以std::numeric_limits<size_t>::max()用于未找到的元素。这是一个有效值,但不可能创建具有这样最大索引的容器。如果std::vector大小等于std::numeric_limits<size_t>::max(),则最大允许索引将为(std::numeric_limits<size_t>::max()-1),因为元素从 0 开始计数。

回答by Naveen

Take a look at the answers provided for this question: Invalid value for size_t?. Also you can use std::find_if with std::distance to get the index.

看看为这个问题提供的答案:Invalid value for size_t? . 您也可以使用 std::find_if 和 std::distance 来获取索引。

std::vector<type>::iterator iter = std::find_if(vec.begin(), vec.end(), comparisonFunc);
size_t index = std::distance(vec.begin(), iter);
if(index == vec.size()) 
{
    //invalid
}

回答by larsmoa

First of all, do you really need to store indices like this? Have you looked into std::map, enabling you to store key => value pairs?

首先,你真的需要像这样存储索引吗?您是否研究过 std::map,使您能够存储键 => 值对?

Secondly, if you used iterators instead, you would be able to return std::vector.end() to indicate an invalid result. To convert an iterator to an index you simply use

其次,如果您改用迭代器,您将能够返回 std::vector.end() 以指示无效结果。要将迭代器转换为索引,您只需使用

size_t i = it - myvector.begin();

回答by sbi

std::vectorhas random-access iterators. You can do pointer arithmetic with them. In particular, this my_vec.begin() + my_vec.size() == my_vec.end()always holds. So you could do

std::vector具有随机访问迭代器。你可以用它们做指针运算。特别是,这my_vec.begin() + my_vec.size() == my_vec.end()始终成立。所以你可以这样做

const vector<type>::const_iterator pos = std::find_if( firstVector.begin()
                                                     , firstVector.end()
                                                     , some_predicate(parameter) );
if( position != firstVector.end() ) {
    const vector<type>::size_type idx = pos-firstVector.begin();
    doAction( secondVector[idx] );
}

As an alternative, there's always std::numeric_limits<vector<type>::size_type>::max()to be used as an invalid value.

作为替代方案,总是std::numeric_limits<vector<type>::size_type>::max()被用作无效值。

回答by Jere.Jones

In this case, it is safe to cast away the unsigned portion unless your vector can get REALLY big.

在这种情况下,丢弃未签名的部分是安全的,除非您的向量可以变得非常大。

I would pull out the where.size() to a local variable since it won't change during the call. Something like this:

我会将 where.size() 拉出到一个局部变量,因为它在调用过程中不会改变。像这样的东西:

int find( const vector<type>& where, int searchParameter ){
    int size = static_cast<int>(where.size());
    for( int i = 0; i < size; i++ ) {
       if( conditionMet( where[i], searchParameter ) ) {
           return i;
       }
    }
    return -1;
}

回答by Mark Ruzon

If a vector has N elements, there are N+1 possible answers for find. std::find and std::find_if return an iterator to the found element OR end() if no element is found. To change the code as little as possible, your find function should return the equivalent position:

如果一个向量有 N 个元素,则 find 有 N+1 个可能的答案。如果未找到元素,则 std::find 和 std::find_if 将迭代器返回到找到的元素或 end() 。要尽可能少地更改代码,您的 find 函数应返回等效位置:

size_t find( const vector<type>& where, int searchParameter )
{
   for( size_t i = 0; i < where.size(); i++ ) {
       if( conditionMet( where[i], searchParameter ) ) {
           return i;
       }
    }
    return where.size();
}
// caller:
const int position = find( firstVector, parameter );
if( position != secondVector.size() ) {
    doAction( secondVector[position] );
}

I would still use std::find_if, though.

不过,我仍然会使用 std::find_if。

回答by GManNickG

Something like this, I think. find_if_counted.hpp:

像这样的事情,我想。find_if_counted.hpp

#ifndef FIND_IF_COUNTED_HPP
#define FIND_IF_COUNTED_HPP

#include <algorithm>

namespace find_if_counted_impl
{
    template <typename Func>
    struct func_counter
    {
        explicit func_counter(Func& func, unsigned &count) :
        _func(func),
        _count(count)
        {
        }

        template <typename T>
        bool operator()(const T& t)
        {
            ++_count;

            return _func(t);
        }

    private:
        Func& _func;
        unsigned& _count;
    };
}

// generic find_if_counted,
// returns the index of the found element, otherwise returns find_if_not_found
const size_t find_if_not_found = static_cast<size_t>(-1);

template <typename InputIterator, typename Func>
size_t find_if_counted(InputIterator start, InputIterator finish, Func func)
{
    unsigned count = 0;
    find_if_counted_impl::func_counter<Func> f(func, count);

    InputIterator result = find_if(start, finish, f);

    if (result == finish)
    {
        return find_if_not_found;
    }
    else
    {
        return count - 1;
    }
}

#endif

Example:

例子:

#include "find_if_counted.hpp"
#include <cstdlib>
#include <iostream>
#include <vector>

typedef std::vector<int> container;

int rand_number(void)
{
    return rand()  % 20;
}

bool is_even(int i)
{
    return i % 2 == 0;
}

int main(void)
{
    container vec1(10);
    container vec2(10);

    std::generate(vec1.begin(), vec1.end(), rand_number);
    std::generate(vec2.begin(), vec2.end(), rand_number);

    unsigned index = find_if_counted(vec1.begin(), vec1.end(), is_even);

    if (index == find_if_not_found)
    {
        std::cout << "vec1 has no even numbers." << std::endl;
    }
    else
    {
        std::cout << "vec1 had an even number at index: " << index <<
            " vec2's corresponding number is: " << vec2[index] << std::endl;
    }
}

Though I feel like I'm doing something silly... :X Any corrections are welcome, of course.

虽然我觉得我在做一些愚蠢的事情... :X 当然,欢迎任何更正。

回答by rashedcs

Take a vector of integer and a key (that we find in vector )....Now we are traversing the vector until found the key value or last index(otherwise).....If we found key then print the position , otherwise print "-1".

取一个整数向量和一个键(我们在 vector 中找到)....现在我们正在遍历该向量,直到找到键值或最后一个索引(否则).....如果我们找到了键,则打印位置,否则打印“-1”。

     #include <bits/stdc++.h>  
     using namespace std;  

     int main()  
      {  
          vector<int>str;  
          int flag,temp key, ,len,num;

           flag=0;
           cin>>len;

           for(int i=1; i<=len; i++)  
           {
               cin>>key;
               v.push_back(key);
           }

           cin>>num;

           for(int i=1; i<=len; i++)  
           {  
             if(str[i]==num)  
             {  
                flag++;  
                temp=i-1;
                break;
             }  
           }

         if(flag!=0)    cout<<temp<<endl;
         else           cout<<"-1"<<endl;   
         str.clear();   

         return 0;  
      }

回答by Basilevs

You probably should not use your own function here. Use find()from STL.

你可能不应该在这里使用你自己的函数。使用find()方法STL

Example:

例子:

list L;
L.push_back(3);
L.push_back(1);
L.push_back(7);

list::iterator result = find(L.begin(), L.end(), 7); assert(result == L.end() || *result == 7);