C++ sorting vector objects error [duplicate] - c++

This question already has answers here:
Standard library sort and user defined types
(3 answers)
Closed 7 years ago.
Sorry for posting a duplicate post but I have my best to find the answer around still couldnt solve the error. I follow many example but it just doesnt seem to work. I having problem with sorting a vector of object.
Its giving me a whole chunk of error on that line of code with sort which i cant even debug.
When i comment out that line it running fine without error.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
//some other codes
vector<PointTwoD> Point;
bool sortByCiv(PointTwoD &d1, PointTwoD &d2) {
return d1.getCivIndex() < d2.getCivIndex();
}
void print_top5()
{
int num = 0;;
cout << "Total no. of records available = " << Point.size() << endl;
cout << "Prining top 5 explorations destinations..." << endl;
**sort(Point.begin(), Point.end(), sortByCiv);**
for (int i = 0; i < 5; i++)
{
num++;
int x, y;
float civ;
x = Point[i].getX();
y = Point[i].getY();
civ = Point[i].getCivIndex();
if (civ > 0){
cout<< num << " Civ Index :" << civ << " at sector (" << x << ", " << y << ")" << endl;
} else {
cout<< num << " <no other records available>" << endl;
}
}
}
I am able to print out the results nicely in the for loop, i just need it to be in descending order. Thanks a lot.
this is the error message
In file included from /usr/include/c++/4.8/algorithm:62:0,
from MissionPlan.cpp:6:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<PointTwoD*, std::vector<PointTwoD> >; _Tp = PointTwoD; _Compare = bool (*)(PointTwoD&, PointTwoD&)]’:
/usr/include/c++/4.8/bits/stl_algo.h:2296:78: required from ‘_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<PointTwoD*, std::vector<PointTwoD> >; _Compare = bool (*)(PointTwoD&, PointTwoD&)]’
/usr/include/c++/4.8/bits/stl_algo.h:2337:62: required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<PointTwoD*, std::vector<PointTwoD> >; _Size = long int; _Compare = bool (*)(PointTwoD&, PointTwoD&)]’
/usr/include/c++/4.8/bits/stl_algo.h:5490:44: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<PointTwoD*, std::vector<PointTwoD> >; _Compare = bool (*)(PointTwoD&, PointTwoD&)]’
MissionPlan.cpp:33:44: required from here
/usr/include/c++/4.8/bits/stl_algo.h:2263:35: error: invalid initialization of reference of type ‘PointTwoD&’ from expression of type ‘const PointTwoD’
while (__comp(*__first, __pivot))
^
/usr/include/c++/4.8/bits/stl_algo.h:2266:34: error: invalid initialization of reference of type ‘PointTwoD&’ from expression of type ‘const PointTwoD’
while (__comp(__pivot, *__last))

First things first - this is not a minimum compilable example. If you could publish something we can compile (say here : http://www.tutorialspoint.com/compile_cpp11_online.php) it would help a lot.
Having said that, your comparison function should take arguments by const reference. In addition, in order to sort in descending order you'd need to change the logic of the predicate as follows:
bool sortByCiv(const PointTwoD &d1, const PointTwoD &d2) {
return d1.getCivIndex() > d2.getCivIndex();
}
edit:
Have a look at this link - this code compiles and you can use it as a reference.
http://goo.gl/kUVP5r

Related

Merging Overlapping Intervals using Stack<pair<int,int>>

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.

what is assertion error with eigen meaning?

When I compute generalized eigen,I write this following code ,and the part of code :
Eigen::MatrixXcf get_Generalized_eigen(const Eigen::MatrixXf &A, const Eigen::MatrixXf &B){
Eigen::GeneralizedEigenSolver<Eigen::MatrixXf> ges;
ges.compute(A, B);
// cout << "The (complex) generalzied eigenvalues are (alphas./beta): " << ges.eigenvalues().transpose() << endl;
cout << ges.eigenvalues().transpose();
}
and my err:
distance_matrix: /usr/include/eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h:204: Eigen::GeneralizedEigenSolver<_MatrixType>::EigenvalueType Eigen::GeneralizedEigenSolver<_MatrixType>::eigenvalues() const [with _MatrixType = Eigen::Matrix<float, -1, -1>; Eigen::GeneralizedEigenSolver<_MatrixType>::EigenvalueType = Eigen::CwiseBinaryOp<Eigen::internal::scalar_quotient_op<std::complex<float>, float>, Eigen::Matrix<std::complex<float>, -1, 1>, Eigen::Matrix<float, -1, 1> >]: Assertion `m_valuesOkay && "GeneralizedEigenSolver is not initialized."' failed.
./setup.sh: line 6: 3609 Aborted ./distance_matrix
can anyone help me ? thank a lot!
i am expecting to know why it happen and how to fix it.

accessing data within nested structures

I am writing a function that prints out a hash table, the structure for this
hash table is
vector< list < Entry > > and the definition of Entry is struct Entry { string key, desc; unsigned num; }; however I am getting errors when i compile this code...
void HT::hTable_print ( )
{
bool lastempty = false;
for(unsigned int i = 0; i < hsize; i++){
list<Entry>& l = hTable[i];
if(!l.empty()){//if list isnt empty
for(unsigned int x = 0; x < l.size();x++){//loop through list
if(lastempty){
cout << endl;
}
Entry e = l.front()+x;
cout << setw(4) << x << ": " << e.key << " - "
<< setw(5) << e.num << " - " << e.desc
<< endl;
}
lastempty = false;
}else{
lastempty = true;
}
}
}
I am trying to loop through the vector and allocate each list element to a variable and then loop through that list printing out the necessary information but I will get errors when I call e.key e.num and e.desc. How do i properly call the information for each Entry structure?
EDIT: Heres a few of the errors I receive when compiling:
hTable.cc:69:24: error: no match for ‘operator+’ (operand types are ‘__gnu_cxx::__alloc_traits<std::allocator<Entry> >::value_type {aka Entry}’ and ‘unsigned int’)
Entry e = l.front()+x;
/usr/include/c++/7/bits/stl_iterator.h:397:5: note: template argument deduction/substitution failed:
hTable.cc:69:25: note: mismatched types ‘const std::reverse_iterator<_Iterator>’ and ‘unsigned int’
Entry e = l.front()+x;
^
/usr/include/c++/7/bits/stl_iterator.h:1198:5: note: template argument deduction/substitution failed:
hTable.cc:69:25: note: mismatched types ‘const std::move_iterator<_IteratorL>’ and ‘unsigned int’
Entry e = l.front()+x;
^
Notice how std::list::front() returns a reference to the first element in list. What you want to do is to take std::list::begin() to have an advancable iterator, std::advance() it and then dereference it:
list<Entry>::const_iterator iter = l.begin();
advance(iter, x);
const Entry& e = *iter;
Or, as per suggestion in the comments, iterate the list via iterators in the first place
unsigned int x = 0;
for (const auto& e : l) {//loop through list
++x;
// .... stuff ...
}

How to compute distance between std::vector<int>::iterator and std::vector<int>::reverse_iterator?

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().

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.