web-dev-qa-db-ja.com

std :: vectorで要素の位置を見つけるにはどうすればよいですか?

another vectorの要素を参照するために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] );
}
_

ただし、vector::size()は、_size_t_を直接格納できないunsigned整数型に対応する_-1_を返します。 intの代わりに_size_t_をインデックスとして使用している場合、ベクターで要素が見つからないことを通知するにはどうすればよいですか?

35
sharptooth

見つからなかった要素にはstd::numeric_limits<size_t>::max()を使用できます。有効な値ですが、そのような最大インデックスを持つコンテナを作成することはできません。 _std::vector_のサイズがstd::numeric_limits<size_t>::max()と等しい場合、要素は0からカウントされるため、許可される最大インデックスは_(std::numeric_limits<size_t>::max()-1)_になります。

15

この質問に対する回答をご覧ください: size_tの無効な値? 。また、std :: findanceとstd :: findanceを使用してインデックスを取得することもできます。

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
}
60
Naveen

まず、このようなインデックスを保存する必要が本当にありますか?キー=>値のペアを保存できるstd :: mapを調べましたか?

第二に、代わりにイテレータを使用した場合、std :: vector.end()を返して無効な結果を示すことができます。イテレータをインデックスに変換するには、単に使用します

size_t i = it - myvector.begin();
17
larsmoa

_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] );
}
_

代替として、常に無効な値として使用されるstd::numeric_limits<vector<type>::size_type>::max()があります。

6
sbi

この場合、ベクトルが本当に大きくならない限り、符号なしの部分を捨てることは安全です。

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;
}
3
Jere.Jones

このようなものだと思います。 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

例:

#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;
    }
}

馬鹿げたことをしているように感じますが...:Xもちろん修正は歓迎します。

2
GManNickG

ベクトルにN個の要素がある場合、検索に対してN + 1個の可能な答えがあります。 std :: findとstd :: find_ifは、見つかった要素にイテレータを返しますOR 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] );
}

ただし、まだstd :: find_ifを使用します。

2
Mark Ruzon

整数のベクトルとキー(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;  
      }
1
rashedcs

ここでは、おそらく独自の関数を使用しないでください。 find() from [〜#〜] stl [〜#〜] を使用します。

例:


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);
1
Basilevs