Merging Overlapping Intervals using Stack<pair<int,int>> - c++

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.

Related

How to create a cartesian product range from filtered data?

I am trying to create a cartesian-product range out of smaller ranges. I thought ranges::v3::view::cartesian_product would work, but somehow it doesn't.
If I try to create a cartesian product using containers directly, I have no problem. The following compiles:
#include <vector>
#include <range/v3/view/cartesian_product.hpp>
int main() {
std::vector<int> data1{1,5,2,7,6,3,4,8,9,0};
std::vector<int> data2{1,5,2,7,6,3,4,8,9,0};
auto range = ranges::v3::view::cartesian_product(data1, data2);
}
However, as soon as I start using filters:
#include <vector>
#include <range/v3/view/cartesian_product.hpp>
#include <range/v3/view/filter.hpp>
int main() {
std::vector<int> data1{1,5,2,7,6,3,4,8,9,0};
std::vector<int> data2{1,5,2,7,6,3,4,8,9,0};
auto range = ranges::v3::view::cartesian_product(
data1 | ranges::v3::view::filter([](int v) { return v%2; }),
data2);
}
I get tons of hard-to-decipher compile errors, starting with:
In file included from contrib/range/v3/view/cartesian_product.hpp:21:0,
from cartesian-err.cpp:2:
contrib/range/v3/range_concepts.hpp: In instantiation of ‘class ranges::v3::cartesian_product_view<ranges::v3::remove_if_view<ranges::v3::iterator_range<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >, ranges::v3::logical_negate_<main()::<lambda(int)> > >, ranges::v3::iterator_range<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > > >’:
cartesian-err.cpp:10:18: required from here
contrib/range/v3/range_concepts.hpp:78:50: error: no match for call to ‘(const ranges::v3::_begin_::fn) (const ranges::v3::remove_if_view<ranges::v3::iterator_range<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> > >, ranges::v3::logical_negate_<main()::<lambda(int)> > >&)’
using iterator_t = decltype(begin(std::declval<T &>()));
~~~~~^~~~~~~~~~~~~~~~~~~~~
How do I get around it?
P.S. Is there somewhere some good documentation of the ranges-v3 library? I can't find any and I feel I am walking in the dark...
Bug or not, one can get around the cartesian_product by implementing it manually, as suggested in https://github.com/ericniebler/range-v3/issues/173.
The added benefit is, that you have better control on the order of iteration, which may have a performance impact if the filter function is expensive.
In the above case, one can implement it like this (shortened the input vectors for brevity):
#include <vector>
#include <iostream>
#include <range/v3/view/for_each.hpp>
#include <range/v3/view/filter.hpp>
int main() {
std::vector<int> data1{1,5,2,7,6};
std::vector<int> data2{1,5,2,7,6};
auto range =
data1
| ranges::v3::view::filter([](int v) { return v%2; })
| ranges::v3::view::for_each([&](int v) {
return data2 | ranges::v3::view::for_each([v](int v2) {
return ranges::v3::yield(std::make_pair(v,v2));
});
});
for (auto&& pair : range) {
std::cout << "[" << pair.first << "," << pair.second << "]\n";
}
return 0;
}
gives the expected output:
[1,1]
[1,5]
[1,2]
[1,7]
[1,6]
[5,1]
[5,5]
[5,2]
[5,7]
[5,6]
[7,1]
[7,5]
[7,2]
[7,7]
[7,6]

How to divide vector by double?

I want to normalize(scale values between 0 and 1 )vector of velocities.
normalized v(i)=v(i)-vmin/(vmax-vmin)
My code
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
vector<double> velocity;
vector<double> results;
double vLower, vUpper, v1;
ifstream inputFile1("/home/milenko/gust/vel.dat");
if (inputFile1) {
double value;
while ( inputFile1 >> value ) {
velocity.push_back(value);
}
}
vLower = *min_element(velocity.begin(), velocity.end());
vUpper = *max_element(velocity.begin(), velocity.end());
v1 = vUpper-vLower;
transform(velocity.begin(), velocity.end(), velocity.begin(), [vLower](double i) -> double { return i - vLower; });
transform (velocity.begin(), velocity.end(), v1, results, divides<double>());
for (auto c : results) { std::cout << c << std::endl; }
}
The first transform is working fine,it subtracts minimum value from each vector element.The problem is with the second one,which should divide the velocity with v1.
In instantiation of ‘_OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation) [with _IIter1 = __gnu_cxx::__normal_iterator<double*, std::vector<double> >; _IIter2 = double; _OIter = std::vector<double>; _BinaryOperation = std::divides<double>]’:
v1.cpp:29:76: required from here
/usr/include/c++/4.8/bits/stl_algo.h:4964:59: error: no match for ‘operator++’ (operand type is ‘std::vector<double>’)
for (; __first1 != __last1; ++__first1, ++__first2, ++__result)
^
/usr/include/c++/4.8/bits/stl_algo.h:4965:37: error: invalid type argument of unary ‘*’ (have ‘double’)
*__result = __binary_op(*__first1, *__first2);
^
/usr/include/c++/4.8/bits/stl_algo.h:4965:2: error: no match for ‘operator*’ (operand type is ‘std::vector<double>’)
*__result = __binary_op(*__first1, *__first2);
Any ideas how to solve this?Or is it possible with single transform?
v1 should not be in transform call.
transform (velocity.begin(), velocity.end(), back_inserter(results),
bind(divides<double>(), placeholders::_1, v1));
But since you use lambda in first transform it will be more simple to use lambda in second transform too.
transform (velocity.begin(), velocity.end(), back_inserter(results),
[&v1](double v) { return v / v1; });
First of all you could use standard algorithm std::minmax_element to find the minimum and the maximum traversing the vector only one time.
And secondly sometimes it is better to write a range-based for loop than to use an algorithm with a lambda expression because in the first case the code will be more readable.
So you can write
auto minmax = std::minmax_element( velocity.begin(), velocity.end() );
auto x = *minmax.first / ( *minmax.second - *mimax.first );
for ( auto &value : velocity ) value -= x;
If you need to create a new vector then you can write insted
auto minmax = std::minmax_element( velocity.begin(), velocity.end() );
auto x = *minmax.first / ( *minmax.second - *mimax.first );
vector<double> results;
resultr.reserve( velocity.size() );
for ( auto value : velocity ) results.push_back( value - x );

C++ Partial Sorting Errors

What I wanted to do is generate n numbers of nearly sorted value.
For example, user will enter nvalue of 1000.
It will then pass the sorting job by calling the partial sorting function.
Basically, I will just sort half of the total values.
Meaning to say, out of 1000 that has been generated..only first half or 500 values will be sorted only.
After done sorting, it shall push all the nearly sorted value into a vector.
However, I was facing some errors which I can't understand what does it mean during compilation. Can anyone help me on these? Thank you
2 following errors:
1)'partial_sort' : ambiguous call to overloaded function c:\users\mk\documents\visual studio 2013\projects\algorithm analysis\algorithm analysis\nearlysorted.cpp 49 1 Algorithm Analysis
2)IntelliSense: more than one instance of overloaded function "partial_sort" matches the argument list:
function template "void partial_sort(rand_access begin, rand_access sort, rand_access end)"
function template "void std::partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last)"
argument types are: (std::_Vector_iterator>>, std::_Vector_iterator>>, std::_Vector_iterator>>) c:\Users\Mk\Documents\Visual Studio 2013\Projects\Algorithm Analysis\Algorithm Analysis\nearlysorted.cpp 49 2 Algorithm Analysis
Code:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
template <class rand_access>//class
void partial_sort(
rand_access begin,
rand_access sort,
rand_access end
);
template <class rand_access, class BinaryPred>//overloading
void partial_sort(
rand_access begin,
rand_access sort,
rand_access end,
BinaryPred comp
);
//Function prototype
//void decrease_store(int val, vector<int> &aVec); TODO SOON
void nearlystd_store(int val, vector<int> &aVec);
int main()
{
int nvalue;
vector<int> int_vector;
cout << "How many numbers would you like to generate?\n";
cin >> nvalue;//get input from user
nearlystd_store(nvalue, int_vector);// pass user input to the function
system("pause");
return 0;
}
void nearlystd_store(int val, vector<int> &aVec)//nearly sorted function
{
vector<int>::iterator Iter;// a vector
int num;
for (int i = 0; i < val; i ++)//generate from the start till desired nvalue
{
aVec.push_back(val - i);//push into this vector
}
partial_sort(aVec.begin(), aVec.begin() + (val / 2), aVec.end());//sort half in the vector
cout << "The Output:\n";
for (Iter = aVec.begin(); Iter != aVec.end(); ++Iter)//push sorted value
{
cout << *Iter << " " << endl;//aVec.push_back(int()); --- Not sure if correct
}
}
EDITTED CODE:
Thanks to both llya & Chris for helping out
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
//Function prototype
//void decrease_store(int val, vector<int> &aVec); TODO SOON
void nearlystd_store(int val, vector<int> &aVec);
int main()
{
int nvalue;
vector<int> int_vector;
cout << "How many numbers would you like to generate?\n";
cin >> nvalue;//get input from user
nearlystd_store(nvalue, int_vector);// pass user input to the function
system("pause");
return 0;
}
void nearlystd_store(int val, vector<int> &aVec)//nearly sorted function
{
vector<int>::iterator Iter;// a vector
for (int i = 0; i < val; i ++)//generate from the start till desired nvalue
{
aVec.push_back(val - i);//push into this vector
}
partial_sort(aVec.begin(), aVec.begin() + (val / 2), aVec.end());//sort half in the vector
cout << "The Output:\n";
for (Iter = aVec.begin(); Iter != aVec.end(); ++Iter)//push sorted value
{
cout << *Iter << " " << endl;//aVec.push_back(int()); --- Not sure if correct
}
}
Let's see compilation errors (next time add it in a question!):
prog.cpp: In function ‘void nearlystd_store(int, std::vector<int>&)’:
prog.cpp:49:68: error: call of overloaded ‘partial_sort(std::vector<int>::iterator, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::vector<int>::iterator)’ is ambiguous
partial_sort(aVec.begin(), aVec.begin() + (val / 2), aVec.end());//sort half in the vector
^
prog.cpp:49:68: note: candidates are:
prog.cpp:8:6: note: void partial_sort(rand_access, rand_access, rand_access) [with rand_access = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]
void partial_sort(
^
In file included from /usr/include/c++/4.8/algorithm:62:0,
from prog.cpp:3:
/usr/include/c++/4.8/bits/stl_algo.h:5308:5: note: void std::partial_sort(_RAIter, _RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]
partial_sort(_RandomAccessIterator __first,
^
Here compiler informs your, that it is hard to decide, which implementation of partial_sort must be called. There are two possible options, so compiler can't be sure, which one is right. You need to avoid such uncertainty. In this case you can rename wrong declaration (i.e. remove all lines from 'template //class' to '//Function prototype').
prog.cpp:43:9: warning: unused variable ‘num’ [-Wunused-variable]
int num;
^
And this is just warning. Here you declared variable num, but never use it. It is better to remove such lines from a code to simplify it.

decltype of boost::make_zip_iterator?

I have the following code:
std::vector<PriceQuote, tbb::scalable_allocator<PriceQuote> > cBids(maxSize);
std::vector<PriceQuote, tbb::scalable_allocator<PriceQuote> > cAsks(maxSize);
auto zipBidsAsks = boost::make_zip_iterator(boost::make_tuple(cBids.begin(), cAsks.begin()));
If I wanted to decltype the return value so that instead of storing it in an auto I can store it in a decltype of whatever boost::make_zip_iterator returns. What does that code look like?
I have tried:
typedef decltype(boost::make_zip_iterator(std::vector<PriceQuote>, std::vector<PriceQuote>)) zipper_type;
// type referred to by zipper_type::iterator
typedef std::iterator_traits<zipper_type::iterator>::value_type zipped_type;
zipped_type zipBidsAsks = boost::make_zip_iterator(boost::make_tuple(cBids.begin(), cAsks.begin()));
But that doesn't even come close to working. Finally, if I want to iterate over zipBidsAsks and get each <0>, <1>. How is that done?
The access code now gives an error:
struct PriceBookEventData
{
timeval ts;
unsigned totalSize;
unsigned maxSize;
typedef decltype
(
boost::make_zip_iterator(boost::tuple<std::vector<PriceQuote>::iterator,
std::vector<PriceQuote>::iterator>())
) zipper_type;
zipper_type zipBidsAsks;
};
void AGUI::HandlePriceBookChange(const PriceBookEventData pbed)
{
int k = 0;
while(0 != stop--)
{
PriceQuote pqb = boost::get<0>(pbed.zipBidsAsks[k]);
PriceQuote pqa = boost::get<1>(pbed.zipBidsAsks[k]);
/data/cbworkspace/AGUI/AGUI.cpp|101|error: no matching function for call to ‘get(boost::detail::operator_brackets_result<boost::zip_iterator<boost::tuples::tuple<__gnu_cxx::__normal_iterator<PriceQuote*, std::vector<PriceQuote> >, __gnu_cxx::__normal_iterator<PriceQuote*, std::vector<PriceQuote> > > >, boost::tuples::cons<PriceQuote&, boost::tuples::cons<PriceQuote&, boost::tuples::null_type> >, boost::tuples::cons<PriceQuote&, boost::tuples::cons<PriceQuote&, boost::tuples::null_type> > >::type)’|
I'm not sure why you want to figure out the type using decltype instead of auto, the latter was designed specifically for cases like this one. Using decltype instead is cumbersome.
You were close with what you tried, except you gave boost::make_zip_iterator a pair of vectors, instead of a tuple of vector interators.
Try this instead
typedef decltype(
boost::make_zip_iterator(
boost::tuple<
std::vector<PriceQuote>::iterator,
std::vector<PriceQuote>::iterator>()
)
) zipper_type;
As for iterating over the zip iterator, here's a simple example:
#include <iostream>
#include <boost/iterator/zip_iterator.hpp>
#include <boost/tuple/tuple.hpp>
#include <vector>
int main()
{
std::vector<int> v1{1,2,3,4}, v2{10,20,30,40};
std::for_each(
boost::make_zip_iterator(boost::make_tuple(v1.begin(), v2.begin())),
boost::make_zip_iterator(boost::make_tuple(v1.end(), v2.end())),
[]( boost::tuple<int, int> const& tup ) {
std::cout
<< boost::get<0>(tup)
<< ", "
<< boost::get<1>(tup)
<< std::endl;
}
);
}
Output:
1, 10
2, 20
3, 30
4, 40

I'm trying to pass a C++ map by reference to a function and iterate through it but I cannot compile the code

I have a fairly simple problem. I'm trying to make a function that accepts a map by reference and iterates through the keys of the map.
#include <map>
#include <string>
#include <sys/types.h>
using namespace std;
void update_fold_score_map(string subfold,
int32_t index,
int32_t subfold_score,
map<string, int32_t> &fold_scores){
for(map<string, int32_t>::iterator i = fold_scores.begin();
i != fold_scores.end();
i ++){
string current_substring;
string fold;
fold = (*i);
current_substring = fold.substr(index, subfold.size());
if (current_substring == subfold){
if (fold_scores[fold] < subfold_score){
fold_scores[fold] = subfold_score;
}
return;
}
}
}
int main(){
return 0;
}
But, I'm getting an error at the line "fold = (*i);" which states:
compilemap.cpp:16:15: error: no match for ‘operator=’ in ‘fold = i.std::_Rb_tree_iterator<_Tp>::operator* [with _Tp = std::pair<const std::basic_string<char>, int>, std::_Rb_tree_iterator<_Tp>::reference = std::pair<const std::basic_string<char>, int>&]()’
fold = (*i); // <- here
fold is of std::string type; whereas (*i) is of map<string, int32_t>::value_type type, which happens to be std::pair<const string, int32_t>.Obviously, you cannot assign later to the former.
What you probably want to do, is to
fold = i->first; // which extracts "key" from the std::map<>::iterator
a map it's a container of pair.
you can access the value part using the -> operator:
fold = i->second;
*i is an std::pair; you should write
fold = i->first
To get the key of the entry.
Try the following instead of fold = (*i)
fold = i->first;