Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I have some vector temp = {1,2,2,3,4}. How to find all elem = 2, save there positions in another vector and delete from the first one.
vector<int> another
vector<int>::iterator it;
for (it = temp.begin(); it != temp.end(); )
{
if (it == elem) { //?
another.push_back(it); //?
temp.erase(it++);
}
else
{
++it;
}
}
std::remove(vec.begin(), vec.end(), 2);
this should do the trick.
(Of course, to actually erase them from the vector, you have to write
vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());
according to the erase-remove idiom.)
Edit: Just noticed:
save there positions in another vector
("with guns in there hands", right?) - basically that doesn't make a lot of sense, the positions will be invalidated when you remove the elements from the container...
To save the positions:
#include <iterator>
for (auto it = temp.begin(); it != temp.end(); ++it)
if (*it == 2)
another.push_back(std::distance(temp.begin(), it));
To erase:
#include <algorithm>
temp.erase(std::remove(temp.begin(), temp.end(), 2), temp.end());
This works for a larger class of containers than just vectors, thanks to the genericity of iterators.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am working on a project where I make various algorithms such as counting and sorting for integers and then I am turning them into template functions so they can be used with things such as vectors and lists.
For example, one templated function looks like this:
template<typename Iter>
int count(Iter* first, Iter* limit, int value)
{
int counter = 0;
while(first != limit)
{
if(*first == value)
++counter;
++first;
}
return counter;
}
When I run some code in my main.cpp such as:
std::vector<int> a = {0, 0, 2, 4, 2, 0};
//I expect count to return 3 for this call...
cout << count(a.begin(), a.end(), 0) << "\n";
It gives me a compiler error:
error: no matching function for call to ‘count(std::vector<int>::iterator, std::vector<int>::iterator, int)’
cout << count(a.begin(), a.end(), 0) << "\n";
I really have tried to figure this out on my own, but it doesn't make sense to me. I have another algorithm called print that prints a vector from vec.begin() to vec.end() that works perfectly fine. I've tried making connections between the one that works and those that don't, but nothing makes logical sense to me.
FOLLOW UP: Could it be that the * in my function definitions are the problem?? Perhaps it is because I have (Iter *first, Iter *last) instead of (Iter first, Iter last)?
Yes, the * in your parameters is the problem. An iterator is not a pointer, but is designed to mimic a pointer (on the other hand, a pointer can be an valid iterator). Do not pass around iterators by pointer, pass them around by value instead, eg:
template<typename Iter>
int count(Iter first, Iter limit, int value)
{
int counter = 0;
while (first != limit)
{
if (*first == value)
++counter;
++first;
}
return counter;
}
On a side note, the standard C++ library already has a std::count() algorithm that does the same thing your count() function does:
#include <vector>
#include <algorithm>
std::vector<int> a = {0, 0, 2, 4, 2, 0};
cout << std::count(a.begin(), a.end(), 0) << "\n";
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
vector<int> v = { 1,2,3,4,5 };
for (auto beg = v.begin(); beg != v.end();++beg)
{
if (beg == v.begin())
v.push_back(50);
}
During run time, it says : "vector iterator not incrementable".
See std::vector::push_back.
If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.
In your example, beg is an iterator. It is being invalidated by the push_back, you cannot use it anymore.
As mentioned std::vector::push_back() may invalidate your iterator. Possible, but pretty ugly solution could be:
for (auto beg = v.begin(); beg != v.end();++beg)
{
if (beg == v.begin()) {
v.push_back(50);
beg = v.begin();
}
}
but your logic seems convoluted, why not push back just before the loop?
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
Here is my code
#include <iostream>
#include <map>
#include <string>
#include <vector>
typedef std::vector<int> VectorInt;
typedef std::map<int, VectorInt> MapVectorInt;
int main() {
MapVectorInt myMap;
VectorInt v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
VectorInt v2;
v2.push_back(2);
v2.push_back(4);
v2.push_back(6);
myMap.insert(std::make_pair(0, v1));
myMap.insert(std::make_pair(1, v2));
return 0;
}
What is the bese way to take (extract/get) the vector at position x (eg 1,2...);
You can use:
auto v1=myMap[0]; //This will do a deep copy for the vector
or:
auto& v1=myMap[0]; //This will hold a reference to the vector
Be careful in the second approach because if the item has removed , the reference will be invalid.
If you want a safe option use std::map::at:
auto v1=myMap.at(0);
or:
auto& v1=myMap.at(0)
This will throw an exception (std::out_of_range) if the item is not there.
Short answer:
Best place to look for it http://en.cppreference.com/w/cpp/container/map/find
With context:
For visualisation only, I guess you should express you intention as you said in your question(get an element from the map and not "eventually" insert it as using [] for accessing a non-existing element creates it), so:
const auto& search = myMap.find(1);
if (search != example.end()) {
for(auto value: search->second) {
std::cout << value << '\n';
}
}
else {
std::cout << "Not found\n";
}
Try It Live
You can refer to the vector in the map with myMap[0] or myMap[1].
You could make an alias for either of those, e.g. auto& x = myMap[0];. Using the alias will access the vector as it is stored in the map.
To take a copy of the vector (so that you can modify the map contents without changing the copy), it is just the same as copying any other object:
auto x = myMap[0];
Note that 0 and 1 refer to the key you used in the insert call; not to the search order or the insertion order (although in your example those things all happen to be the same).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am writing two functions, the first one does a linear search and is supposed to return the position of the first found value if it is in the vector. The second method is a binary search that is done using equal_range and it is supposed to return the same thing as the linear search. Currently they are checking every value as a match. Any help is appreciated.
int linearSearch( const vector<int>& vec, int z)
{
vector<int>::iterator iter = find(vec.begin(), vec.end(), z);
if (iter != vec.end())
return (iter-vec.begin());
else
return -1;
}
int binarySearch( const vector<int>& vec, int z)
{
pair<vector<int>::const_iterator, vector<int>::const_iterator> bounds;
bounds = equal_range(vec.begin(),vec.end(), z);
if (bounds.first != vec.end())
return (bounds.first -vec.begin());
else
return -1;
}
Your description is unclear, but I'll point out some concerns with the code.
In binarySearch() search, there is
bounds = equal_range(vec.begin(),vec.end(), z);
if (bounds.first != v.end())
return (bounds.first -v.begin());
v is not declared anywhere. If the code compiles then, presumably, it is declared somewhere in code you haven't shown. But it may have no relationship to vec. The behaviour of the code (particularly the return) will be undefined.
A rather fundamental difference between the functions is because std::equal_range() assumes a sorted (or partitioned) range, and std::find() does not.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
If I have these two vectors:
vec1: "hello", "world"
vec2: "it", "is", "sunny", "today"
resultvector: "helloit", "worldis"
I need to use stl for this, and a functor. So far what I have throws a stackdump error:
My functor:
reads in two std strings, and "+" them together, returns result of operation.
My function:
Creates a std::list list, and uses std::transform(vec1.begin(), vec1.end(), vec2.begin(), list.begin(), functor()); return list;
My suspicion is that I don't know how to make it iterate only till the end of smaller container, and also maybe I am doing something funky with list.begin() and need something else for it.
Any ideas on how I might accomplish this?
Note: the two vectors are std::vector<string> and result is std::list<string>
Thank you in advance for your help!
In your transform call, use back_inserter(list) in place of list.begin(). back_inserter produces an iterator that translates assignments into push_back calls on underlying container.
std::transform(
vec1.begin(),
vec1.begin()+std::min(vec1.size(),vec2.size()),
vec2.begin(),
std::back_inserter(list),
functor()
);
#include<iostream>
#include<algorithm>
using namespace std;
struct ff
{
string operator ()(const string& x, const string& y ){
return x+y; }
};
int main ()
{
vector <string> vec1{"hello", "world"};
vector <string> vec2{ "it", "is", "sunny", "today"};
vector <string> resultvector;
std::transform(
vec1.begin(), vec1.begin()+min(vec1.size(),vec2.size()),
vec2.begin(),
back_inserter(resultvector),
ff()
);
for(auto i:resultvector)
cout<<i<<endl;
}