2009-09-15 17 views
32

は私がに別のベクトルの要素を参照するためにそれを使用するのstd ::ベクトルの要素の位置を見つける必要がある。しかしunsigned整数型に対応vector::size()戻りsize_tstd :: 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]); 
} 

をそのことはできません直接-1を保管してください。 intの代わりにsize_tを使用すると、その要素がベクトルに見つからないことをどのように通知できますか?

+8

質問のタイトルを変更する必要があります。問題は要素の位置を見つける方法ではなく、2つのベクトルの要素を参照することです。 –

+0

問題が-1の場合は、[here](http://www.cplusplus.com/reference/climits/)をご覧になるか、 'return(size_t)-1;' – ST3

答えて

14

見つからなかった要素にはstd::numeric_limits<size_t>::max()を使用できます。これは有効な値ですが、そのような最大インデックスを持つコンテナを作成することは不可能です。 std::vectorstd::numeric_limits<size_t>::max()に等しい大きさを有する場合、要素は0

56

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 
} 
+7

を使うか、 iteratorを 'where.end()'と比較し、等しくない場合にのみ距離を計算/使用します。パフォーマンスには影響しません。検索の直後に成功のチェックを保持します。 –

1

あなた自身の機能をここでは使用しないでください。 find()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

イテレータを別のベクトルに転送する必要があります。 – GManNickG

+0

Yeap、それはまさに私の問題です。イテレータは大丈夫ですが、別のベクトルで直接使用することはできません。 – sharptooth

3

、未署名の部分を捨てても安全です。

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

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

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

size_t i = it - myvector.begin(); 
2

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

例:Xの任意の修正が歓迎されている、もちろん:

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

私は...愚かな何かをやっているように私は感じるけど。

+0

find_if_counted_implというのはやや馬鹿なことです。 :)あなたがランダムアクセス反復子を持っていない場合、インデックスはほとんど無駄です。あなたがランダムアクセスイテレータを持っているならば、found_it - begin()を引くことができます。また、begin()+ size()はいくつかの目的に役立つイテレータを生成することができますが、begin()はsize() +符号なし(-1)は何もしません。特にチェックする必要があります。 – UncleBens

6
std::vector

から数えたので、次に最大許容指数は、(std::numeric_limits<size_t>::max()-1)なりランダムアクセスイテレータを有しています。それらを使ってポインタ演算を行うことができます。特に、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()が常にあります。

2

ベクトルに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]); 
} 

私はまだstd :: find_ifを使用します。

+0

'where.size()'を返すための+1。それはそれを返すために完全な意味があります。関数がイテレータを代わりに返す場合、 'where.end()'を返すという考え方と一致しています。 – Nawaz

1

整数とベクトルのベクトルをとってみましょう....今度はベクトル値を見つけるまでベクトルをトラバースしています(そうでない場合).....キーが見つかったら位置を印字し、そうでなければ "-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

あなたのポストにあなたのコードを説明してください –

+1

整数とキー(配列で見つけたもの)の配列を取る....今はキー値または最後のインデックスが見つかるまで配列インデックスをトラバースしています.....見つかったらインデックスを印刷し、それ以外の場合は "-1"を印刷します。 – rashedcs

+0

@rashedcs答えを編集して、あなたのコメントをコメントに含めてください! –

関連する問題