I'm merging overlapping intervals like
5 12, 1 8, 14 19, 22 28, 25 27, 27 30
So I use the logic using pair<int, int> template But I can't push pair elements into the Stack<pair<int,int>> because what I'm pushing is (&int, &int) instead of (int, int). So what can I do...
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
void mergeOverlappingIntervals(vector<vector<int>> &arr){
vector<pair<int,int>> v;
for(int i=0;i<arr.size();i++){
v.push_back(make_pair(arr[i][0],arr[i][1]));
}
sort(v.begin(),v.end());
// for(auto x:v){
// cout<<x.first<<" "<<x.second<<endl;
// }
stack<pair<int,int>> st;
st.push(v[0].first,v[0].second);
for(int i=1;i<v.size();i++){
int top = st.top();
if(v[i].first <= top.second){
top.second = max(top.second,v[i].second);
}
st.push(v[i].first,v[i].second);
}
while(!st.empty()){
int top = st.top();
cout<<top.fist << " " << top.second<<endl;
st.pop();
}
}
int main() {
int n;
cin>>n;
vector<vector<int>> arr(n, vector<int>(2,0));
for(int i=0;i<n;i++){
cin>>arr[i][0];
cin>>arr[i][1];
}
mergeOverlappingIntervals(arr);
return 0;
}
You must have misunderstood the error message. As you did not include it, I cannot explain it to you.
When I try to compile I get following error message:
<source>: In function 'void mergeOverlappingIntervals(std::vector<std::vector<int> >&)':
<source>:16:12: error: no matching function for call to 'std::stack<std::pair<int, int> >::push(int&, int&)'
16 | st.push(v[0].first,v[0].second);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/stack:61,
from <source>:4:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_stack.h:260:7: note: candidate: 'void std::stack<_Tp, _Sequence>::push(const value_type&) [with _Tp = std::pair<int, int>; _Sequence = std::deque<std::pair<int, int>, std::allocator<std::pair<int, int> > >; value_type = std::pair<int, int>]'
260 | push(const value_type& __x)
| ^~~~
[...]
And this is because std::stack< std::pair<int,int> >::push has a single parameter, not two. You can find documentation here: https://en.cppreference.com/w/cpp/container/stack/push
You could use std::make_pair as you did when pushing to the vector. Actually pushing to the vector is analogous to pushing to the stack. Though you do not need std::make_pair in either case. Just add a pair of {} to construct the pair:
st.push({v[i].first,v[i].second});
Alternatively you can use emplace. It does take parameters that are then forwarded to the elements constructor.
I'm attempting to use a seeded random_shuffle to simply shuffle a vector, before I use it. I tested this out by doing
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <bits/stdc++.h>
using namespace std;
int seed;
int rng(int i)
{
srand(seed);
return rand()%i;
}
int main()
{
vector<int> myVec;
cin >> seed;
for (int i = 0; i < 10; ++i)
myVec.push_back(i);
for (auto it = myVec.begin(); it != myVec.end(); ++it)
cout << *it;
cout << endl;
random_shuffle(myVec.begin(), myVec.end(), rng);
for (auto it = myVec.begin(); it != myVec.end(); ++it)
cout << *it;
}
and it worked just fine. This lets me enter an int for the seed, and then prints out the before and after. However, when I tried to insert it into a class and run a build task with VSCode, it exploded.
class Test
{
public:
Test(int seed)
{
random = seed;
for (int i = 0; i < 10; ++i)
myVec2.push_back(i);
random_shuffle(myVec2.begin(), myVec2.end(), r);
}
private:
vector<int> myVec2;
int random;
int r(int i)
{
srand(random);
return rand()%i;
}
};
Here's the errors that came up:
25:54 required from here
error: must use '.*' or '->*' to call pointer-to-member function in '__rand (...)', e.g. '(... ->* __rand) (...)'
4619 | _RandomAccessIterator __j = __first + __rand((__i - __first) + 1);
Why is random_shuffle functioning correctly in main(), but not a class?
rng is a global function. r is a member function of a class.
Consider it from the viewpoint of random_shuffle. When it wants to call r, on what object will it call it? Since it knows nothing about your class it simply won't be able to. This is what the error message is trying to tell you (clumsily).
One typical way would be to make int r(int i) static. But then, you won't have access to random. A more modern way would be to use a lambda:
random_shuffle(myVec2.begin(), myVec2.end(), [this](int i){return r(i);} );
Basically, the lambda is an object wrapping a function that calls r(i) for you, but on the this pointer.
As #cigien recommends, using shuffle instead would be a very good idea as the standard changed a long time ago. See: https://en.cppreference.com/w/cpp/algorithm/random_shuffle This would remove the need for r or rng altogether and get rid of this question :-)
I tried using std::distance like this :
vi::iterator frontIter = resVec.begin();
vi::reverse_iterator backIter = resVec.rbegin();
if(std::distance(frontIter , backIter))
{
std::cout << " ! " << std::endl;
}
But the compiler gives me this error.
partion.cpp:46:39: note: candidate is:
In file included from /usr/include/c++/4.9/bits/stl_algobase.h:66:0,
from /usr/include/c++/4.9/vector:60,
from test.h:1,
from partion.cpp:1:
/usr/include/c++/4.9/bits/stl_iterator_base_funcs.h:114:5: note: template<class _InputIterator> typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator)
distance(_InputIterator __first, _InputIterator __last)
^
/usr/include/c++/4.9/bits/stl_iterator_base_funcs.h:114:5: note: template argument deduction/substitution failed:
partion.cpp:46:39: note: deduced conflicting types for parameter ‘_InputIterator’ (‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ and ‘std::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >’)
if(std::distance(frontIter , backIter))
So how I find the distance between these two iterators. Better yet, is there a way to solve this problem without using the back_iterator, but two standard iterators ?
for(size idx = 0 ; idx < vec.size() ; ++idx)
{
if(idx == n)
{
continue;
}
if(vec[idx] < partVal) // insert in front of partVal
{
*frontIter = vec[idx];
++frontIter;
}
else // insert at back of n
{
*backIter = vec[idx];
++backIter;
}
}
Note :
using vi = std::vector<int>;
using size = std::size_t;
Any reverse iterator can be converted to its underlying forward iterator via base().
So what you want is:
std::distance(v.begin(), v.rbegin().base())
Which will give you the same result as v.size().
This question showed how to use erase/remove_if based on vector indices using a function predicate. This works well the first time the function is called but because the local static variable maintains state, on the next call to a different vector I'd be out of luck. So I thought I could use a functor with a private variable that would be re-usable. It mostly works except for the first element. There's something specific to the way remove_if uses the functor that messes up initialization of the private variable
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace std;
class is_IndexEven_Functor {
public:
is_IndexEven_Functor() : k(0) {}
bool operator()(const int &i) {
cout << "DEBUG: isIndexEvenFunctor: k " << k << "\ti " << i << endl; ////
if(k++ % 2 == 0) {
return true;
} else {
return false;
}
}
private:
int k;
};
int main() {
is_IndexEven_Functor a;
a(0);
a(1);
a(2);
a(3);
vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
cout << "\nBefore\n";
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ")); cout << endl;
is_IndexEven_Functor b;
v.erase( remove_if(v.begin(), v.end(), b), v.end() );
cout << "\nAfter\n";
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ")); cout << endl;
return 0;
}
Here's the output:
DEBUG: isIndexEvenFunctor: k 0 i 0
DEBUG: isIndexEvenFunctor: k 1 i 1
DEBUG: isIndexEvenFunctor: k 2 i 2
DEBUG: isIndexEvenFunctor: k 3 i 3
Before
0 1 2 3
DEBUG: isIndexEvenFunctor: k 0 i 0
DEBUG: isIndexEvenFunctor: k 0 i 1 // why is k == 0 here ???
DEBUG: isIndexEvenFunctor: k 1 i 2
DEBUG: isIndexEvenFunctor: k 2 i 3
After
2
The crux of the question is why is the value of k equal to 0 on the second call to the functor (and how do I fix it)?
I'm guessing this has something to do with remove_if using it as temporary object or something but I don't really understand what that means.
EDIT: it would be great if I could avoid c++11
Yes, the implementation is allowed to copy the function, so you can get confusing behavior if the functional has mutable state. There are a couple of ways to work around this. The easiest is probably to use a std::reference_wrapper, which can be created using the std::ref function:
is_IndexEven_Functor b;
v.erase( remove_if(v.begin(), v.end(), std::ref(b)), v.end() );
Now, instead of making a copy of the function object, the implementation copies a wrapper, so there is only one instance of the original function object.
Another option is to keep the index separate from the function:
class is_IndexEven_Functor {
public:
is_IndexEven_Functor(int &index) : k(index) {}
.
.
.
private:
int &k;
};
and use it like this:
int index = 0;
is_IndexEven_Functor b(index);
v.erase( remove_if(v.begin(), v.end(), b), v.end() );
Generally, functors with state are not so great for STL algorithms, as they do not guarantee anything about the handling of functor. For all it cares, it could create a new copy of the functor (from the original!) for every iteration to perform checks. STL assumes functors are stateless.
To overcome this, you should use references to state inside your functors (in your case, have your k a reference to int, which is initialized before) or pass functors themselves in reference wrappers. To answer particular question (that is, what's happening in the remove_if), let's take a look into the implementation (one of implementations, of course):
__remove_if(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred)
{
__first = std::__find_if(__first, __last, __pred);
if (__first == __last)
return __first;
_ForwardIterator __result = __first;
++__first;
for (; __first != __last; ++__first)
if (!__pred(__first))
{
*__result = _GLIBCXX_MOVE(*__first);
++__result;
}
return __result;
}
As you see, it is using a COPY of a predicate for find_if, and than continues with original predicate from found position - but original knows nothing about new position, reflected in the copy.
This question already has answers here:
How can I sort two vectors in the same way, with criteria that uses only one of the vectors?
(9 answers)
Closed 9 months ago.
I have several std::vector, all of the same length. I want to sort one of these vectors, and apply the same transformation to all of the other vectors. Is there a neat way of doing this? (preferably using the STL or Boost)? Some of the vectors hold ints and some of them std::strings.
Pseudo code:
std::vector<int> Index = { 3, 1, 2 };
std::vector<std::string> Values = { "Third", "First", "Second" };
Transformation = sort(Index);
Index is now { 1, 2, 3};
... magic happens as Transformation is applied to Values ...
Values are now { "First", "Second", "Third" };
friol's approach is good when coupled with yours. First, build a vector consisting of the numbers 1…n, along with the elements from the vector dictating the sorting order:
typedef vector<int>::const_iterator myiter;
vector<pair<size_t, myiter> > order(Index.size());
size_t n = 0;
for (myiter it = Index.begin(); it != Index.end(); ++it, ++n)
order[n] = make_pair(n, it);
Now you can sort this array using a custom sorter:
struct ordering {
bool operator ()(pair<size_t, myiter> const& a, pair<size_t, myiter> const& b) {
return *(a.second) < *(b.second);
}
};
sort(order.begin(), order.end(), ordering());
Now you've captured the order of rearrangement inside order (more precisely, in the first component of the items). You can now use this ordering to sort your other vectors. There's probably a very clever in-place variant running in the same time, but until someone else comes up with it, here's one variant that isn't in-place. It uses order as a look-up table for the new index of each element.
template <typename T>
vector<T> sort_from_ref(
vector<T> const& in,
vector<pair<size_t, myiter> > const& reference
) {
vector<T> ret(in.size());
size_t const size = in.size();
for (size_t i = 0; i < size; ++i)
ret[i] = in[reference[i].first];
return ret;
}
typedef std::vector<int> int_vec_t;
typedef std::vector<std::string> str_vec_t;
typedef std::vector<size_t> index_vec_t;
class SequenceGen {
public:
SequenceGen (int start = 0) : current(start) { }
int operator() () { return current++; }
private:
int current;
};
class Comp{
int_vec_t& _v;
public:
Comp(int_vec_t& v) : _v(v) {}
bool operator()(size_t i, size_t j){
return _v[i] < _v[j];
}
};
index_vec_t indices(3);
std::generate(indices.begin(), indices.end(), SequenceGen(0));
//indices are {0, 1, 2}
int_vec_t Index = { 3, 1, 2 };
str_vec_t Values = { "Third", "First", "Second" };
std::sort(indices.begin(), indices.end(), Comp(Index));
//now indices are {1,2,0}
Now you can use the "indices" vector to index into "Values" vector.
Put your values in a Boost Multi-Index container then iterate over to read the values in the order you want. You can even copy them to another vector if you want to.
Only one rough solution comes to my mind: create a vector that is the sum of all other vectors (a vector of structures, like {3,Third,...},{1,First,...}) then sort this vector by the first field, and then split the structures again.
Probably there is a better solution inside Boost or using the standard library.
You can probably define a custom "facade" iterator that does what you need here. It would store iterators to all your vectors or alternatively derive the iterators for all but the first vector from the offset of the first. The tricky part is what that iterator dereferences to: think of something like boost::tuple and make clever use of boost::tie. (If you wanna extend on this idea, you can build these iterator types recursively using templates but you probably never want to write down the type of that - so you either need c++0x auto or a wrapper function for sort that takes ranges)
I think what you really need (but correct me if I'm wrong) is a way to access elements of a container in some order.
Rather than rearranging my original collection, I would borrow a concept from Database design: keep an index, ordered by a certain criterion. This index is an extra indirection that offers great flexibility.
This way it is possible to generate multiple indices according to different members of a class.
using namespace std;
template< typename Iterator, typename Comparator >
struct Index {
vector<Iterator> v;
Index( Iterator from, Iterator end, Comparator& c ){
v.reserve( std::distance(from,end) );
for( ; from != end; ++from ){
v.push_back(from); // no deref!
}
sort( v.begin(), v.end(), c );
}
};
template< typename Iterator, typename Comparator >
Index<Iterator,Comparator> index ( Iterator from, Iterator end, Comparator& c ){
return Index<Iterator,Comparator>(from,end,c);
}
struct mytype {
string name;
double number;
};
template< typename Iter >
struct NameLess : public binary_function<Iter, Iter, bool> {
bool operator()( const Iter& t1, const Iter& t2 ) const { return t1->name < t2->name; }
};
template< typename Iter >
struct NumLess : public binary_function<Iter, Iter, bool> {
bool operator()( const Iter& t1, const Iter& t2 ) const { return t1->number < t2->number; }
};
void indices() {
mytype v[] = { { "me" , 0.0 }
, { "you" , 1.0 }
, { "them" , -1.0 }
};
mytype* vend = v + _countof(v);
Index<mytype*, NameLess<mytype*> > byname( v, vend, NameLess<mytype*>() );
Index<mytype*, NumLess <mytype*> > bynum ( v, vend, NumLess <mytype*>() );
assert( byname.v[0] == v+0 );
assert( byname.v[1] == v+2 );
assert( byname.v[2] == v+1 );
assert( bynum.v[0] == v+2 );
assert( bynum.v[1] == v+0 );
assert( bynum.v[2] == v+1 );
}
A slightly more compact variant of xtofl's answer for if you are just looking to iterate through all your vectors based on the of a single keys vector. Create a permutation vector and use this to index into your other vectors.
#include <boost/iterator/counting_iterator.hpp>
#include <vector>
#include <algorithm>
std::vector<double> keys = ...
std::vector<double> values = ...
std::vector<size_t> indices(boost::counting_iterator<size_t>(0u), boost::counting_iterator<size_t>(keys.size()));
std::sort(begin(indices), end(indices), [&](size_t lhs, size_t rhs) {
return keys[lhs] < keys[rhs];
});
// Now to iterate through the values array.
for (size_t i: indices)
{
std::cout << values[i] << std::endl;
}
ltjax's answer is a great approach - which is actually implemented in boost's zip_iterator http://www.boost.org/doc/libs/1_43_0/libs/iterator/doc/zip_iterator.html
It packages together into a tuple whatever iterators you provide it.
You can then create your own comparison function for a sort based on any combination of iterator values in your tuple. For this question, it would just be the first iterator in your tuple.
A nice feature of this approach is that it allows you to keep the memory of each individual vector contiguous (if you're using vectors and that's what you want). You also don't need to store a separate index vector of ints.
This would have been an addendum to Konrad's answer as it an approach for a in-place variant of applying the sort order to a vector. Anyhow since the edit won't go through I will put it here
Here is a in-place variant with a slightly higher time complexity that is due to a primitive operation of checking a boolean. The additional space complexity is of a vector which can be a space efficient compiler dependent implementation. The complexity of a vector can be eliminated if the given order itself can be modified.
Here is a in-place variant with a slightly higher time complexity that is due to a primitive operation of checking a boolean. The additional space complexity is of a vector which can be a space efficient compiler dependent implementation. The complexity of a vector can be eliminated if the given order itself can be modified. This is a example of what the algorithm is doing.
If the order is 3 0 4 1 2, the movement of the elements as indicated by the position indices would be 3--->0; 0--->1; 1--->3; 2--->4; 4--->2.
template<typename T>
struct applyOrderinPlace
{
void operator()(const vector<size_t>& order, vector<T>& vectoOrder)
{
vector<bool> indicator(order.size(),0);
size_t start = 0, cur = 0, next = order[cur];
size_t indx = 0;
T tmp;
while(indx < order.size())
{
//find unprocessed index
if(indicator[indx])
{
++indx;
continue;
}
start = indx;
cur = start;
next = order[cur];
tmp = vectoOrder[start];
while(next != start)
{
vectoOrder[cur] = vectoOrder[next];
indicator[cur] = true;
cur = next;
next = order[next];
}
vectoOrder[cur] = tmp;
indicator[cur] = true;
}
}
};
Here is a relatively simple implementation using index mapping between the ordered and unordered names that will be used to match the ages to the ordered names:
void ordered_pairs()
{
std::vector<std::string> names;
std::vector<int> ages;
// read input and populate the vectors
populate(names, ages);
// print input
print(names, ages);
// sort pairs
std::vector<std::string> sortedNames(names);
std::sort(sortedNames.begin(), sortedNames.end());
std::vector<int> indexMap;
for(unsigned int i = 0; i < sortedNames.size(); ++i)
{
for (unsigned int j = 0; j < names.size(); ++j)
{
if (sortedNames[i] == names[j])
{
indexMap.push_back(j);
break;
}
}
}
// use the index mapping to match the ages to the names
std::vector<int> sortedAges;
for(size_t i = 0; i < indexMap.size(); ++i)
{
sortedAges.push_back(ages[indexMap[i]]);
}
std::cout << "Ordered pairs:\n";
print(sortedNames, sortedAges);
}
For the sake of completeness, here are the functions populate() and print():
void populate(std::vector<std::string>& n, std::vector<int>& a)
{
std::string prompt("Type name and age, separated by white space; 'q' to exit.\n>>");
std::string sentinel = "q";
while (true)
{
// read input
std::cout << prompt;
std::string input;
getline(std::cin, input);
// exit input loop
if (input == sentinel)
{
break;
}
std::stringstream ss(input);
// extract input
std::string name;
int age;
if (ss >> name >> age)
{
n.push_back(name);
a.push_back(age);
}
else
{
std::cout <<"Wrong input format!\n";
}
}
}
and:
void print(const std::vector<std::string>& n, const std::vector<int>& a)
{
if (n.size() != a.size())
{
std::cerr <<"Different number of names and ages!\n";
return;
}
for (unsigned int i = 0; i < n.size(); ++i)
{
std::cout <<'(' << n[i] << ", " << a[i] << ')' << "\n";
}
}
And finally, main() becomes:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
void ordered_pairs();
void populate(std::vector<std::string>&, std::vector<int>&);
void print(const std::vector<std::string>&, const std::vector<int>&);
//=======================================================================
int main()
{
std::cout << "\t\tSimple name - age sorting.\n";
ordered_pairs();
}
//=======================================================================
// Function Definitions...
**// C++ program to demonstrate sorting in vector
// of pair according to 2nd element of pair
#include <iostream>
#include<string>
#include<vector>
#include <algorithm>
using namespace std;
// Driver function to sort the vector elements
// by second element of pairs
bool sortbysec(const pair<char,char> &a,
const pair<int,int> &b)
{
return (a.second < b.second);
}
int main()
{
// declaring vector of pairs
vector< pair <char, int> > vect;
// Initialising 1st and 2nd element of pairs
// with array values
//int arr[] = {10, 20, 5, 40 };
//int arr1[] = {30, 60, 20, 50};
char arr[] = { ' a', 'b', 'c' };
int arr1[] = { 4, 7, 1 };
int n = sizeof(arr)/sizeof(arr[0]);
// Entering values in vector of pairs
for (int i=0; i<n; i++)
vect.push_back( make_pair(arr[i],arr1[i]) );
// Printing the original vector(before sort())
cout << "The vector before sort operation is:\n" ;
for (int i=0; i<n; i++)
{
// "first" and "second" are used to access
// 1st and 2nd element of pair respectively
cout << vect[i].first << " "
<< vect[i].second << endl;
}
// Using sort() function to sort by 2nd element
// of pair
sort(vect.begin(), vect.end(), sortbysec);
// Printing the sorted vector(after using sort())
cout << "The vector after sort operation is:\n" ;
for (int i=0; i<n; i++)
{
// "first" and "second" are used to access
// 1st and 2nd element of pair respectively
cout << vect[i].first << " "
<< vect[i].second << endl;
}
getchar();
return 0;`enter code here`
}**
with C++11 lambdas and the STL algorithms based on answers from Konrad Rudolph and Gabriele D'Antona:
template< typename T, typename U >
std::vector<T> sortVecAByVecB( std::vector<T> & a, std::vector<U> & b ){
// zip the two vectors (A,B)
std::vector<std::pair<T,U>> zipped(a.size());
for( size_t i = 0; i < a.size(); i++ ) zipped[i] = std::make_pair( a[i], b[i] );
// sort according to B
std::sort(zipped.begin(), zipped.end(), []( auto & lop, auto & rop ) { return lop.second < rop.second; });
// extract sorted A
std::vector<T> sorted;
std::transform(zipped.begin(), zipped.end(), std::back_inserter(sorted), []( auto & pair ){ return pair.first; });
return sorted;
}
So many asked this question and nobody came up with a satisfactory answer. Here is a std::sort helper that enables to sort two vectors simultaneously, taking into account the values of only one vector. This solution is based on a custom RadomIt (random iterator), and operates directly on the original vector data, without temporary copies, structure rearrangement or additional indices:
C++, Sort One Vector Based On Another One