J'ai besoin de trouver une position d'élément dans un vecteur std :: pour l'utiliser pour référencer un élément dans n autre vecteur:
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] );
}
cependant vector::size()
renvoie size_t
qui correspond à un type intégral unsigned
qui ne peut pas stocker directement -1
. Comment puis-je signaler que l'élément n'est pas trouvé dans un vecteur lorsque j'utilise size_t
Au lieu de int
comme index?
Vous pouvez utiliser std::numeric_limits<size_t>::max()
pour les éléments introuvables. C'est une valeur valide, mais il est impossible de créer un conteneur avec un tel index max. Si std::vector
A une taille égale à std::numeric_limits<size_t>::max()
, alors l'index maximum autorisé sera (std::numeric_limits<size_t>::max()-1)
, Puisque les éléments sont comptés à partir de 0.
Jetez un œil aux réponses fournies pour cette question: valeur non valide pour size_t? . Vous pouvez également utiliser std :: find_if avec std :: distance pour obtenir l'index.
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
}
Tout d'abord, avez-vous vraiment besoin de stocker des indices comme celui-ci? Avez-vous examiné std :: map, vous permettant de stocker des paires clé => valeur?
Deuxièmement, si vous utilisiez des itérateurs à la place, vous seriez en mesure de retourner std :: vector.end () pour indiquer un résultat invalide. Pour convertir un itérateur en index, vous utilisez simplement
size_t i = it - myvector.begin();
std::vector
Possède des itérateurs à accès aléatoire. Vous pouvez faire de l'arithmétique des pointeurs avec eux. En particulier, cette my_vec.begin() + my_vec.size() == my_vec.end()
est toujours valable. Donc tu pourrais faire
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] );
}
Comme alternative, il y a toujours std::numeric_limits<vector<type>::size_type>::max()
à utiliser comme valeur invalide.
Dans ce cas, il est sûr de supprimer la partie non signée à moins que votre vecteur ne devienne vraiment grand.
Je retirerais where.size () en une variable locale car elle ne changera pas pendant l'appel. Quelque chose comme ça:
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;
}
Quelque chose comme ça, je pense. 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
Exemple:
#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;
}
}
Bien que j'ai l'impression de faire quelque chose de stupide ...: X Toutes les corrections sont les bienvenues, bien sûr.
Si un vecteur a N éléments, il y a N + 1 réponses possibles pour trouver. std :: find et std :: find_if renvoient un itérateur à l'élément trouvé OR end () si aucun élément n'est trouvé. Pour changer le code le moins possible, votre fonction find doit retourner le position équivalente:
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] );
}
J'utiliserais quand même std :: find_if.
Prenez un vecteur d'entier et une clé (que nous trouvons dans le vecteur) .... Maintenant, nous traversons le vecteur jusqu'à ce que la valeur de la clé ou le dernier index soit trouvé (sinon) ..... Si nous avons trouvé la clé, imprimez la position, sinon, imprimez "-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;
}