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 );
Related
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 want find the element v[0][0]=1 v[0][1]=2 of the vector v with the use of lambda function and find of stl.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
vector<vector<int>> v(3);
v[0].resize(2);
v[1].resize(2);
v[2].resize(2);
int n=1, m = 2;
v[0][0]=1; v[0][1]=2;
v[1][0]=0; v[1][1]=0;
v[2][0]=2; v[2][1]=3;
auto it = find(v.begin(), v.end(), [=]( vector<int> vet) {return (vet[0] == n && vet[1] == m);} );
return 0;
}
error: no match for 'operator==' (operand types are 'std::vector'
and 'const main()::)>')|
I don't understand the problem: both vet[0] and n are integer so the operator== should be defined.
I think you meant to use find_if. Moreover the syntax should be changed a bit. Also, m and n are parameters, that the lambda function should receive as parameters. So change your code to this:
auto it = find_if(v.begin(), v.end(), [n, m] (const vector<int>& vet) {return (vet[0] == n && vet[1] == m);} );
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().
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 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;