Как делают я нахожу положение элемента в станд.:: вектор?

Можно попробовать некоторые программы, предложенные здесь:

TEX к ASCII

35
задан Adrian McCarthy 19 September 2016 в 20:03
поделиться

8 ответов

Вы можете использовать std :: numeric_limits :: max () для элементов, которые не были найдены. Это допустимое значение, но создать контейнер с таким максимальным индексом невозможно. Если std :: vector имеет размер, равный std :: numeric_limits :: max () , то максимально допустимый индекс будет (std :: numeric_limits :: max () - 1) , так как элементы отсчитываются от 0.

16
ответ дан 27 November 2019 в 06:31
поделиться

Взгляните на ответы на этот вопрос : Недопустимое значение для 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
}
60
ответ дан 27 November 2019 в 06:31
поделиться

Во-первых, действительно ли вам нужно хранить такие индексы? Вы изучали std :: map, позволяющую хранить пары ключ => значение?

Во-вторых, если бы вы использовали вместо этого итераторы, вы могли бы вернуть std :: vector.end (), чтобы указать недопустимый результат. Чтобы преобразовать итератор в индекс, вы просто используете

size_t i = it - myvector.begin();
17
ответ дан 27 November 2019 в 06:31
поделиться

std::vector has 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

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::size_type>::max() to be used as an invalid value.

6
ответ дан 27 November 2019 в 06:31
поделиться

В этом случае безопасно отбросить беззнаковую часть, если только ваш вектор не может стать ДЕЙСТВИТЕЛЬНО большим.

Я бы вытащил 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
ответ дан 27 November 2019 в 06:31
поделиться

Думаю, что-то вроде этого. 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
ответ дан 27 November 2019 в 06:31
поделиться

Если вектор имеет N элементов, существует N + 1 возможных ответов для находить. std :: find и std :: find_if возвращают итератор к найденному элементу ИЛИ end (), если элемент не найден. Чтобы изменить код как можно меньше, ваша функция поиска должна возвращать эквивалентную позицию:

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
ответ дан 27 November 2019 в 06:31
поделиться

Вероятно, вам не следует использовать здесь свою собственную функцию. Используйте find () из STL .

Пример:

 список L;
L.push_back (3);
L.push_back (1);
L.push_back (7); 

list :: iterator result = find (L.begin (), L.end (), 7); assert (результат == L.end () || * результат == 7);

1
ответ дан 27 November 2019 в 06:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: