我需要在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}}整数类型。使用-1
而不是size_t
作为索引时,如何表示在向量中找不到元素?
答案 0 :(得分:60)
查看为此问题提供的答案: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
}
答案 1 :(得分:17)
首先,你真的需要存储像这样的指数吗?您是否查看了std :: map,使您能够存储key =&gt;价值对?
其次,如果您使用迭代器,则可以返回std :: vector.end()以指示无效结果。要将迭代器转换为索引,只需使用
即可size_t i = it - myvector.begin();
答案 2 :(得分:15)
您可以将std::numeric_limits<size_t>::max()
用于未找到的元素。它是一个有效值,但不可能创建具有此类最大索引的容器。如果std::vector
的大小等于std::numeric_limits<size_t>::max()
,则允许的最大索引将为(std::numeric_limits<size_t>::max()-1)
,因为元素从0开始计算。
答案 3 :(得分:6)
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()
用作无效值。
答案 4 :(得分: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;
}
答案 5 :(得分: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
示例:
#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当然欢迎任何更正。
答案 6 :(得分:2)
如果一个向量有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。
答案 7 :(得分: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);
答案 8 :(得分: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;
}
答案 9 :(得分:0)
完全摆脱向量的概念
template< typename IT, typename VT>
int index_of(IT begin, IT end, const VT& val)
{
int index = 0;
for (; begin != end; ++begin)
{
if (*begin == val) return index;
}
return -1;
}
这将为您提供更大的灵活性,并允许您使用类似的结构
int squid[] = {5,2,7,4,1,6,3,0};
int sponge[] = {4,2,4,2,4,6,2,6};
int squidlen = sizeof(squid)/sizeof(squid[0]);
int position = index_of(&squid[0], &squid[squidlen], 3);
if (position >= 0) { std::cout << sponge[position] << std::endl; }
您还可以依次搜索其他任何容器。