используя find (), чтобы найти элементы в векторе - PullRequest
1 голос
/ 03 января 2011

У меня есть вектор, в котором хранятся некоторые целые числа. В этом векторе могут быть все числа, кроме 10, 12, 31 не могут появляться вместе или в парах, то есть 10 и 12, 10 и 31, 12 и 31, 10 12 и 31 являются недействительными Я придумал следующий подход:

int main(){ 
int a[] = {10,2,31}; //can be of any size
vector<int> v(a, a+3);
short cnt = 0;
if(find(v.begin(), v.end(), 10) != v.end())
 ++cnt;
if(find(v.begin(), v.end(), 12) != v.end())
 ++cnt;
if(find(v.begin(), v.end(), 31) != v.end())
 ++cnt;

if(cnt > 1) 
  cout<<"Invalid options";
else 
  cout<<"Valid options";

return EXIT_SUCCESS;
}

который работает. Есть лучший способ сделать это? Тем более, что вектор может содержать любое количество элементов, может ли быть какой-либо недостаток?

Ответы [ 4 ]

4 голосов
/ 03 января 2011

А как насчет count:

template <class InputIterator, class T>
  typename iterator_traits<InputIterator>::difference_type
    count ( ForwardIterator first, ForwardIterator last, const T& value );

(см. http://www.cplusplus.com/reference/algorithm/count/)

или count_if (который просматривает список только один раз):

template <class InputIterator, class Predicate>
  typename iterator_traits<InputIterator>::difference_type
    count_if ( ForwardIterator first, ForwardIterator last, Predicate pred );

, которая требует незначительной дополнительной работы предиката, что-то вроде:

bool checkvalues(int i) {
    return (i==10 || i==12 || i==31);
}

или вы можете быть более умным и создать класс с operator(), если хотите указать возможные значения во время выполнения.

(см. http://www.cplusplus.com/reference/algorithm/count_if/)

Является ли проблема с недопустимыми парами и тройками красной сельдью?

2 голосов
/ 03 января 2011

Если вы сортируете их, вы можете использовать std::binary_search, который будет работать быстрее, когда количество элементов в векторе велико (должно быть очень большим, хотя, чтобы иметь какую-либо заметную разницу).

std::sort(v.begin(), v.end());
if (std::binary_search(v.begin(), v.end(), 10)) cnt++;
if (std::binary_search(v.begin(), v.end(), 12)) cnt++;
if (std::binary_search(v.begin(), v.end(), 31)) cnt++;
0 голосов
/ 03 января 2011

Вы можете попробовать set_intersection, как в примере ниже:

int a[] = {10,2,12}; //can be of any size
int b[] = {10,12,31}; // set we are interested in, sorted already to save a sort

sort (a, a+3);

vector<int> dest(sizeof(a)/sizeof(a[0])); // matching items will go here
vector<int>::iterator it;

it = set_intersection (a, a+3, b, b+3, dest.begin());

if (distance(dest.begin(), it) > 1) // oops means more than one item has matched...
0 голосов
/ 03 января 2011

Вы всегда должны использовать квадратные скобки в операторах if, даже если инструкция занимает всего 1 строку.

if(find(v.begin(), v.end(), 31) != v.end())
 ++cnt;

Чтение кода может привести к путанице без скобок.И если вы хотите добавить к этому условию еще один оператор, вы можете ввести очень сложную для отладки ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...