Find the mode (most common element) of an array in C++ - c++

I had this on an interview question. I'd like to see how StackOverflow would do it.
What would Bjarne Stroustrop think of my way? It's a little wordy, but I don't know how to make it better, unfortunately. I know you guys are gonna laugh at my stupidity.
template <class T>
T mode(T* arr, size_t n)
// If there's a tie, return an arbitrary element tied for 1st
// If the array size is 0, throw an error
{
if (n == 0)
{
throw("Mode of array of size 0 is undefined, bro.");
}
else if (n == 1)
{
return arr[0];
}
else
{
std::pair<T, int> highest(arr[0], 1);
std::map<T, int> S;
S.insert(highest);
for (T* thisPtr(arr + 1), lastPtr(arr+n); thisPtr != lastPtr; ++thisPtr)
{
if (S.count(*thisPtr) == 0)
{
S.insert(std::pair<T, int> (*thisPtr, 1);
}
else
{
++S[*thisPtr];
if (S[*thisPtr] > highest.second)
{
highest = std::pair<T, int> (*thisPtr, S[*thisPtr]);
}
}
}
}
}

You could do this, provided that T implements std::hash:
std::unordered_multiset<T> elems;
std::for_each(arr, arr + size, [&elems](T const & elem) { elems.insert(elem); }
//Now you have elems.count() for each entry
auto max_count = /*Guaranteed minimum value*/
T mode{};
for (auto const & set_elem : elems) {
if (max(elems.count(set_elem), max_count) == max_count)) {
mode = set_elem;
}
}

I think I'd use an std::map to do the counting, then find the item with the largest count:
template <class T>
T mode(T* arr, size_t n) {
std::map<T, size_t> counts;
for (size_t i=0; i<n; i++)
++counts[arr[i]];
return max_element(counts.begin(), counts.end(),
[](std::pair<T, size_t> const &a, std::pair<T, size_t> const &b) {
return a.second < b.second;
})->first;
}
If you expect a really large number of unique items, you might want to use an std::unordered_map instead of a std::map [should reduce expected complexity from O(n log n) to O(N)].

I found the following issues with your code.
Redundant check n == 1
You can remove the block
else if (n == 1)
{
return arr[0];
}
without affecting the outcome.
Declaration of the variables in the for loop:
T* thisPtr(arr + 1), lastPtr(arr+n);`
is equivalent to
T* thisPtr(arr + 10); T lastPtr(arr+n);
That's not what your intention is. The compiler will report an error too. So, move their declaration outside the for loop. Change
for (T* thisPtr(arr + 1), lastPtr(arr+n); thisPtr != lastPtr; ++thisPtr)
to
T* thisPtr(arr + 1);
T* lastPtr(arr+n);
for ( ; thisPtr != lastPtr; ++thisPtr)
Simplify the contents of the for loop
The lines
if (S.count(*thisPtr) == 0)
{
S.insert(std::pair<T, int> (*thisPtr, 1));
}
can be replaced by
++S[*thisPtr];
which is exactly what you are doing in the following else block.
You can change the contents of the entire for loop to:
++S[*thisPtr];
if (S[*thisPtr] > highest.second)
{
highest = std::pair<T, int> (*thisPtr, S[*thisPtr]);
}
You need to return the mode
Add
return highest.first;
before the closing of the else block.

Related

Problems with constant iterators

I'm trying write a tempate function which takes a sequence (by 2 iterators) and calculates the number of permutations of this sequence, in which there are no consecutive identical elements.
Thats what i did
template<class Iterator>
size_t count_perm(Iterator p, Iterator q)
{
if (p == q)
return 1;
size_t count = 0;
while(std::next_permutation(p, q)){
if(std::adjacent_find(p,q) != q)
++count;
}
}
/*Example
std::array<int, 3> a1 = {1,2,3};
size_t c1 = count_perm(a1.begin(), a1.end()); // 6
std::array<int, 5> a2 = {1,2,3,4,4};
size_t c2 = count_perm(a2.begin(), a2.end()); // 36*/
This code not working if i pass const iterators. What should I change to make it work with const iterators?
This code not working if i pass const iterators. What should I change to make it work with const iterators?
You can't: std::next_permutation() modify the values so is incompatible with const iterators.
-- EDIT --
The OP ask
How can i implement this function in right way?
I suggest you to follows the suggestion from Jarod42: works over a copy.
I propose something as follows
template <class Container>
size_t count_perm (Container c) // note: c is a copy
{
if ( c.cbegin() == c.cend() )
return 1;
size_t count = 0U;
std::sort(c.begin(), c.end());
if (std::adjacent_find(c.cbegin(), c.cend()) != c.cend()))
{
std::size_t ui = c.size();
for ( count = ui ; --ui > 1 ; count *= ui )
;
// count now is c.size() ! (factorial of)
}
else
{
while (std::next_permutation(c.begin(), c.end()))
if (std::adjacent_find(c.cbegin(), c.cend()) != c.cend())
++count;
}
return count; // remember this return!
}
Fixed your templated function for you (still requires non-const iterators):
template<class Iterator> size_t count_perm(Iterator p, Iterator q)
{
if (p == q || std::all_of(p, q, [&](auto &el) {return el == *p; })))
return 0;
size_t count = 1;
std::sort(p, q);
while (std::next_permutation(p, q))
if (std::adjacent_find(p, q) == q)
++count;
return count;
}
you should return count
when no adjacent elements are found, std::adjacent_find returns end, so you should == q not != q
Your example produces 6 and 37. Should it be 36 instead of 37?
Solved this exercise as follows, it works with const iterators:
template<class Iterator>
size_t count_permutations(Iterator p, Iterator q)
{
using T = typename std::iterator_traits<Iterator>::value_type;
if (p == q)
return 1;
std::vector<T> v(p,q);
std::sort(v.begin(), v.end());
size_t count = 0;
do{
if(std::adjacent_find(v.begin(),v.end()) == v.end()) {
++count;
}
} while(std::next_permutation(v.begin(), v.end()));
return count;
}
Problem was to use std::type_traits<Iterator>::value_type instead Iterator::value_type (that not working with const iters and simple pointers (like int*))

c++: Remove Elements that are in one vector from another

I need to remove the elements that appear in Vector A and Vector B, but keep the elements that are only in Vector A. The vectors can be of any size, but are not necessarily equal to each other.
For example, if:
vector A contains the values <1,4,66,22>
vector B contains the values <1,22,44,93,102,543>
Then after preforming the operation:
vector A should contain <4,66>
vector B should contain <44,93,102,543>
Do I need to loop through both with a for loop and strncmp the values or is the a function that I can use to streamline the process?
This is what I tried but doesn't seem to work.
string rawInput;
string fileInput;
vector<string> stdInput; //vector to hold standard input values
vector<string> fileList; //vector to hold file values
sizeIn = stdInput.size();
sizeFile = fileList.size();
if (sizeIn >= sizeFile)
{
for (count = 0;count <= sizeIn; count++)
{
for (count1 = 0; count1 <= sizeFile; count1++)
{
if (stdInput[count1] == fileList[count])
{
stdInput.erase(stdInput.begin()+count1-1);
fileList.erase(fileList.begin()+count-1);
}
}
}
}
else
{
for (count = 0; count <= sizeFile; count ++)
{
for (count1 = 0; count1 <= sizeIn; count1++)
{
if (stdInput[count] == fileList[count1])
{
stdInput.erase(stdInput.begin()+count-1);
fileList.erase(fileList.begin()+count1-1);
}
}
}
}
That's a lot of work there. I would have suggested std::set_difference, but since you want to do it in place, this code will do it for you with good algorithmic complexity:
template<typename T>
void remove_intersection(std::vector<T>& a, std::vector<T>& b){
std::unordered_multiset<T> st;
st.insert(a.begin(), a.end());
st.insert(b.begin(), b.end());
auto predicate = [&st](const T& k){ return st.count(k) > 1; };
a.erase(std::remove_if(a.begin(), a.end(), predicate), a.end());
b.erase(std::remove_if(b.begin(), b.end(), predicate), b.end());
}
Isn't C++ beautiful? :-)
A Demo:
int main(){
std::vector<int> a = {1,4,66,22};
std::vector<int> b = {1,22,44,93,102,543};
remove_intersection(a, b);
for(auto k : a) std::cout << k << ' ';
std::cout << std::endl;
for(auto k : b) std::cout << k << ' ';
}
Outputs:
4 66
44 93 102 543
See it Live On Coliru
There are many variations of the above method. For example, if you are worried that count may take too long when such count is really large, you can implement a simple function to find and count up to at most 2 elements; another one: you can simply use two different unordered sets.
No, I will resort them via sort(fileList.begin(), fileList.end() ); after
So asymptotically it's the same to sort before.
Using set_difference, you can do something like:
template<typename T>
void remove_intersection(std::vector<T>* c1, std::vector<T>* c2) {
assert(c1 != nullptr);
assert(c2 != nullptr);
std::sort(std::begin(*c1), std::end(*c1)); // O(n1 logn1)
std::sort(std::begin(*c2), std::end(*c2)); // O(n2 logn2)
std::vector<T> difference1, difference2;
difference1.reserve(c1->size());
difference2.reserve(c2->size());
std::set_difference(std::begin(*c1), std::end(*c1),
std::begin(*c2), std::end(*c2),
std::back_inserter(difference1));
// O(2*[N1 + N2 - 1])
std::set_difference(std::begin(*c2), std::end(*c2),
std::begin(*c1), std::end(*c1),
std::back_inserter(difference2));
// O(2*[N1 + N2 - 1])
*c1 = std::move(difference1); // O(1)
*c2 = std::move(difference2); // O(1)
}
Thanks to #WhiZTiM for the great code example.
For my application it had some issues:
only applicable to vectors
removes duplicates from a although they are not in b
does not pay attention to const correctness
This suggested variation deals with those issues.
template <typename ContainerT>
void remove_intersection(ContainerT& a, ContainerT& b)
{
std::unordered_set<ContainerT::value_type> const uniqueAs { a.cbegin(), a.cend() };
std::unordered_multiset<ContainerT::value_type> st { uniqueAs.cbegin(), uniqueAs.cend() };
st.insert(b.begin(), b.end());
auto const predicate = [&st](ContainerT::value_type const& k) { return st.count(k) > 1; };
a.erase(std::remove_if(a.begin(), a.end(), predicate), a.cend());
b.erase(std::remove_if(b.begin(), b.end(), predicate), b.cend());
}
I might try something like the following.
// Create sets from vectors. This eliminates the duplicate elements.
const unordered_set<int> setA{vecA.cbegin(), vecA.cend()};
const unordered_set<int> setB{vecB.cbegin(), vecB.cend()};
PopulateSetDiff(vecA, setA, setB);
PopulateSetDiff(vecB, setB, setA);
// Populate 'vec' with 'set1 - set2'
template <typename T>
void PopulateSetDiff(
vector<T>& vec,
unordered_set<T> const& set1,
unordered_set<T> const& set2) {
vec.clear();
for (const auto elem : set1) {
if (set2.find(elem) == set2.cend()) {
vec.push_back(elem);
}
}
vec.shrink_to_fit();
}
for (auto& d : deleteCommands) {
auto it = stackCommands.begin();
while (it != stackCommands.end()) {
if (d == *it._Ptr) {
commands[d]->Exit(this);
it = stackCommands.erase(it);
}
else { it++; }
}
}

How to iterate through a list but stop at size-1

This code:
for (std::list<point>::const_iterator it = controlPoints->begin();
it != controlPoints->end();
++it) {
...
}
Corresponds to:
for (int i = 0; i < controlPoints->size; i++) {
...
}
Meaning, it would iterate through all elements of the list if I got one element for each time it looped.
What would correspond to:
for (int i = 0; i < controlPoints->size-1; i++) {
...
}
I mean, how can I loop size-1 times using iterators?
The obvious way would be to get an iterator to the end and decrement it:
auto stop = controlPoints.end();
--stop;
for (std::list<point>::const_iterator it = controlPoints->begin();
it != stop;
++it) {
...
}
You could use std::advance or std::next if you preferred, but for this case a simple decrement is fine.
controlPoints->end() is also an iterator.
You could do this:
std::list<point>::const_iterator it = controlPoints->begin();
std::list<point>::const_iterator stop = controlPoints->end();
if ( it != stop) for ( --stop; it != stop; ++it) {
...
}
More verbose but it's safe to use whether the list has 0, 1 or more elements.
The key here is that iterators can be incremented and (for bidirectional iterators) decremented to advance / recede the position, so it's the equivalent of doing:
int it = 0;
int stop = list.size();
if (it != stop) for( --stop; it < stop; ++it ) {
...
}
In C++11 you should seek to use the ranged based for loop as often as you can. for(;;) loops are complex and error prone at the point you write them.
Using for(:) loops requires complexity away from the point you write them, but because you can write that infrastructure once and reuse it the bugs in it can be ironed out, instead of being dispursed throughout the code.
To start with, here is a simple range_t:
template<class It>
struct range_t {
It b, e;
It begin() const { return b; }
It end() const { return e; }
std::size_t size() const { return std::distance(begin(), end()); }
using iterator_tag = typename std::iterator_traits<It>::iterator_category;
private:
static It safe_advance( It in, It bound, std::ptrdiff_t n, std::random_access_iterator_tag ) const {
if (n == 0) return in;
if (n < 0) n = (std::min)( n, -std::distance( bound, in ) );
if (n > 0) n = (std::max)( n, std::distance( in, bound ) );
return std::advance( in, n );
}
static It safe_advance( It in, It bound, std::ptrdiff_t n, ... ) const {
if (n == 0) return in;
while (n < 0 && in != bound) {
in = std::prev(in); --n;
}
while (n > 0 && in != bound) {
in = std::next(in); ++n;
}
return in;
}
public:
range_t without_back( std::size_t n = 1 ) const {
return {begin(), safe_advance( end(), begin(), -(std::ptrdiff_t)n, iterator_tag{} };
}
range_t without_front( std::size_t n = 1 ) const {
return {begin(), safe_advance( end(), begin(), n, iterator_tag{} };
}
bool empty() const { return begin() == end(); }
decltype(auto) front() const { return *begin(); }
decltype(auto) back() const { return *std::prev(end()); }
};
template<class It>
range_t<It> range( It b, It e ) { return {b,e}; }
// rvalues blocked:
template<class C, class It = decltype( std::begin(std::declval<C&>()) )>
range_t<It> range( C& c ) { return range( std::begin(c), std::end(c) ); }
it stores a range of iterators and is itself iterable.
Then:
auto r = range(*controlPoints).without_back();
is a range object that is the controlPoints without the last element.
Using ranged-based for you can do this:
for (auto& x : range(*controlPoints).without_back()) {
}
note that the above code carefully handles being fed an empty array.
We can also write a similar adapter that lets you iterator over the iterators. I usually do this by writing an index_iterator that stores an Index and passes ++ and == etc to it. Except when you * it simply returns a copy of the Index.
This is useful to create an iterator over integers, but also lets you create an iterator over iterators.
Then create a range of indexes to the iterators in your container, and you get syntax that looks like:
for (auto it : iterators_into( *controlPoints) ) {
}
giving you range-based loops that also gives you iterators if you need them.

c++ vector with max N equal elements' positions

Can I get the positions of the max N elements (the equal max elements) using predefined function in STL?
A solution I thought of is:
vector<int> maxN(vector<int> original){
vector<int> result;
auto pt = max_element(original.begin(),original.end());
int max = *pt;
while(*pt == max){
result.push_back(distance(original.begin(),pt));
*pt = 0;//assumed that all the elements in original are greater than 0
pt = max_element(original.begin(),original.end());
}
return result;
}
There must be a more elegant way to do this.
It depends on your exact requirements:
std::max_element gives you the maximum element. std::copy_if can be used to copy all elements equal to the maximum (and limit the maximum number if required, e.g. using a lambda).
std::nth_element partially sorts a range (e.g. your vector) such the first n entries are equal or less to anything that follows. The first n elements are not sorted themselves. And it is not a stable partition.
std::partial_sort gives you the same, but the first n elements are sorted. Again, not a stable partition/sort.
Combine std::nth_element + std::stable_partition + std::stable_sort if you need a stable selection of the first n elements and you want them stably sorted.
Once you have found the max element, make another linear pass over the vector to find all the matching elements. Setting to 0 is not needed when doing it this way. The original vector is being passed by value, so setting to 0 was not being seen by the caller. This makes for a very clear implementation:
vector<int> maxN(vector<int> original){
vector<int> result;
if (original.empty()) return result;
const int max = *(max_element(original.begin(), original.end()));
for (int i = 0; i < original.size(); ++i) {
if (original[i] == max) result.push_back(i);
}
return result;
}
It is more importatnt to implement clear and maintainable code than to attempt to extract maximal reuse from the C++ library.
If your goal is to not use an explicit loop over the passed in original vector, but use some standard C++ template algorithm, I recommend creating a helper iterator to help you recover the index.
struct indexer {
int i_;
indexer (int i = 0) : i_(i) {}
indexer & operator ++ () { ++i_; return *this; }
indexer operator ++ (int) { ++i_; return i_ - 1; }
int operator * () const { return i_; }
bool operator != (indexer rhs) const { return i_ != rhs.i_; }
//... whatever else is required for copy_if
};
Then, you can invoke copy_if with a simple lambda and a back insert iterator:
copy_if(indexer(), indexer(original.size()), back_inserter(result),
[&](int i) -> bool { return original[i] == max; });
However, this is more obscure than the straightforward loop presented above.
As variant (can check on a cpp.sh)
#include <iostream>
#include <vector>
int main ()
{
std::vector<int>elems = {10, 20, 10, 30, 5, 30, 8, 30, 18, 12};
for(size_t i=0; i<elems.size()-1; i++)
{
if(elems[i+1] > elems[i]) { elems.erase(elems.begin()+i); i=-1;}
else if(elems[i+1] < elems[i]) { elems.erase(elems.begin()+i+1); i=-1;}
}
return 0;
}
You could decorate your original with indices, take the Nth element-approach, and strip off the indices again (test on cpp.sh):
template<typename T, typename less = std::greater<T>>
std::vector<int> max_indices(
int N,
const std::vector<T> &original,
less predicate = less())
{
auto decorated = with_indices(original);
// the gist of the problem
const auto nth = std::next(begin(decorated), N);
std::nth_element(begin(decorated), nth, end(decorated),
with_indices(predicate));
std::sort(begin(decorated), nth,
with_indices(predicate));
decorated.erase(nth, end(decorated));
return indices(decorated);
}
int main()
{
std::vector<int> values{ {1, 2, 3 , 4, 5, 6, 7, 8, 9, 10} };
auto m = max_indices(4, values);
assert(4u == m.size());
assert(9 == m[0]);
assert(8 == m[1]);
assert(7 == m[2]);
assert(6 == m[3]);
return 0;
}
Where these functions do the decorating/undecorating:
template<typename T>
std::vector<std::pair<T, int>> with_indices(const std::vector<T> &original)
{
std::vector< std::pair<T, int> > decorated;
std::transform(begin(original), end(original), std::back_inserter(decorated),
[index = 0](T t) mutable {
return std::make_pair(t, index++);
});
return decorated;
}
template<typename T>
std::vector<int> indices(const std::vector<std::pair<T, int>> &original)
{
std::vector<int> undecorated;
std::transform(begin(original), end(original), std::back_inserter(undecorated),
[](auto p) mutable {
return p.second;
});
return undecorated;
}
template<typename Function>
auto with_indices(Function f)
{
return [&](auto... args) {
return f(args.first...);
};
}

How do I find an element position in std::vector?

I need to find an element position in an std::vector to use it for referencing an element in another 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] );
}
however vector::size() returns size_t which corresponds to an unsigned integral type that can't directly store -1. How do I signal that the element is not found in a vector when using size_t instead of int as an index?
Take a look at the answers provided for this question: Invalid value for size_t?. Also you can use std::find_if with std::distance to get the 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
}
First of all, do you really need to store indices like this? Have you looked into std::map, enabling you to store key => value pairs?
Secondly, if you used iterators instead, you would be able to return std::vector.end() to indicate an invalid result. To convert an iterator to an index you simply use
size_t i = it - myvector.begin();
You could use std::numeric_limits<size_t>::max() for elements that was not found. It is a valid value, but it is impossible to create container with such max index. If std::vector has size equal to std::numeric_limits<size_t>::max(), then maximum allowed index will be (std::numeric_limits<size_t>::max()-1), since elements counted from 0.
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<vector<type>::size_type>::max() to be used as an invalid value.
In this case, it is safe to cast away the unsigned portion unless your vector can get REALLY big.
I would pull out the where.size() to a local variable since it won't change during the call. Something like this:
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;
}
If a vector has N elements, there are N+1 possible answers for find. std::find and std::find_if return an iterator to the found element OR end() if no element is found. To change the code as little as possible, your find function should return the equivalent position:
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] );
}
I would still use std::find_if, though.
Something like this, I think. 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
Example:
#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;
}
}
Though I feel like I'm doing something silly... :X Any corrections are welcome, of course.
You probably should not use your own function here.
Use find() from STL.
Example:
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);
Take a vector of integer and a key (that we find in vector )....Now we are traversing the vector until found the key value or last index(otherwise).....If we found key then print the position , otherwise print "-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;
}
Get rid of the notion of vector entirely
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;
}
This will allow you more flexibility and let you use constructs like
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; }
You could also search any other container sequentially as well.