Sorting a vector of pairs <int,int> [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
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.
Closed 8 years ago.
Improve this question
How to sort a vector of pairs in descending order when the pair is incr<int,int>using the std::sort() in STL?It should sort first with respect to the first element and then the second.

The operator< is overloaded for pair<int,int> so you can sort a vector of pairs just like any other vector. If you need descending order, you have two options - either sort and then call std::reverse to reverse the result or provide predicate for the sorting.
You can also make use of std::greater:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<pair<int, int> > a;
a.push_back(make_pair(1, 2));
a.push_back(make_pair(2, 3));
sort(a.begin(), a.end(), greater<pair<int,int> >());
return 0;
}

use this,
template<class T>
struct sortFunctor: public unary_function<std::pair<int, int>, std::pair<int, int>>
{
bool operator()(const std::pair<int, int>& First, const std::pair<int, int>& Second)
{
if(First.first < Second.first)
{
return false;
}
if(First.first == Second.first && First.second < Second.second)
{
return false;
}
return true;
}
}
then pass this functor as a third parameter to sort function.

Related

Descending order sorting on basis of first element in vector of pair is not giving desired results [closed]

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 3 years ago.
Improve this question
In below shared code link ,Sorting the vector elements on the basis of first element of pairs in descending order is performed but it looks like sorting is not happening and expected output is not received.Here first iterative value needs to be printed in descending order and for the same below
code is written in iterateVector() function.
sort(vect.begin(),vect.end(),[] (const pair<double,double> &a,
const pair<double,double> &b){return (a.first > b.first);});
http://coliru.stacked-crooked.com/a/d868271155375b17
Actual output:
first iterative value =30 second iterative value=300
first iterative value =45.3 second iterative value=300
first iterative value =23 second iterative value=301
first iterative value =175 second iterative value=303
Expected output:
first iterative value =175 second iterative value=303
first iterative value =45.3 second iterative value=300
first iterative value =30 second iterative value=300
first iterative value =23 second iterative value=301
You can fix this by :
static declaration of vector in order to associate this vector with
all objects.
iterateVector also needs to be declared static (Access the static vector)
#include <iostream>
#include <vector>
#include<algorithm>
#include<memory>
class State
{
public:
static void iterateVector();
explicit State
(
const double& stateValue,
const double& stateCommand
)
: _stateValue(stateValue),_stateCommand(stateCommand)
{
_mvect.push_back( std::make_pair(_stateValue,_stateCommand) );
}
private:
const double& _stateValue;
const double& _stateCommand;
static std::vector< std::pair <double,double> > _mvect ;
};
void State::iterateVector()
{
sort(_mvect.begin(),_mvect.end(),[] (const std::pair<double,double> &a,
const std::pair<double,double> &b){return (a.first > b.first);});
for (auto &itr : _mvect )
{
std::cout<<"first iterative value ="<<itr.first<<" ";
std::cout<<"second iterative value="<<itr.second<<std::endl;
}
}
std::vector< std::pair <double,double> > State::_mvect ;
int main()
{
std::vector< std::pair <double,double> > vect ;
std::vector<std::unique_ptr<State> > obj;
obj.emplace_back(std::move(new State(30,300)));
obj.emplace_back(std::move(new State(45.3,300)));
obj.emplace_back(std::move(new State(23,301)));
obj.emplace_back(std::move(new State(175,303)));
State::iterateVector();
return 0;
}
You've made four vectors, each with one element.
Not one vector with four elements.

Store character pointer in map in order std::map<char*, int> mymap. Storing it as character or string not an option [closed]

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
std::map<char*, int> mymap;
mymap['a'] = 1;
mymap['b'] = 2;
mymap['c'] = 3;
How to print 1, 2, 3 in that particular order if order of insertion gets changed?
I don't know the insertion order . But the order of output should be same everytime.
I don't know the insertion order . But the order of output should be same everytime.
This is exactly how std::map works. The iterators go through the element in the strict weak ordering induced by the comparator of the map. Insertion order does not affect the order of the iteration.
std::map<char*, int> How to print 1, 2, 3 in that particular order.
The problem here is that a map is ordered by the key rather than by value.
If you need to iterate over elements of a map in value-order, then it seems that you need a multi-index container. Such container can be looked up by one index, and iterated using another index. The C++ standard library does not provide such multi-index containers however.
The idea of multi-index container is quite simple. It consists of nodes just like a list or a tree does, but each node contains multiple sets of links - one for each index. A generic implementation of such container is not quite as simple as the idea is.
mymap['a'] = 1;
You cannot use a char as a lookup argument to a map whose key type is char*.
This is probably what you need:
std::map<char, int> mymap;
mymap.emplace(make_pair('a', 1));
mymap.emplace(make_pair('c', 3));
mymap.emplace(make_pair('b', 2));
for(auto& it : mymap)
cout<<it.second<<endl;
map is sorted based on the keys not the values, If you need a variable size char then use string
if char* is not optional use shared_ptr:
std::map<std::shared_ptr<char>, int> mymap;
mymap.emplace(make_shared<char>(char('a')), 1);
The main problem you have here is inserting a pointer as key means you always have unique key, for example two pointers point to different addresses in memory but the char stored in those addresses are the same which is not what you want from a map.
if you wanted to keep it sorted based on the values just change the key and value.
sort map by value:
#include <iostream>
#include <memory>
#include <algorithm>
#include <map>
using namespace std;
template<typename A, typename B>
std::pair<B,A> flip_pair(const std::pair<A,B> &p)
{
return std::pair<B,A>(p.second, p.first);
}
template<typename A, typename B>
std::multimap<B,A> flip_map(const std::map<A,B> &src)
{
std::multimap<B,A> dst;
std::transform(src.begin(), src.end(), std::inserter(dst, dst.begin()),
flip_pair<A,B>);
return dst;
}
int main(void)
{
std::map<std::shared_ptr<char>, int> mymap;
std::shared_ptr<char> a;
a.reset(new char('a'));
std::shared_ptr<char> b;
b.reset(new char('b'));
std::shared_ptr<char> c;
c.reset(new char('c'));
mymap.emplace(make_pair(a, 1));
mymap.emplace(make_pair(c, 2));
mymap.emplace(make_pair(b, 3));
std::multimap<int, std::shared_ptr<char>> dst = flip_map(mymap);
// dst is now sorted by what used to be the value in src!
for(auto& it : dst)
cout<<it.first<<endl;
}
credit of sorting map by value: https://stackoverflow.com/a/5056797/10933809

initilize unordered_map with a vector in c++ [closed]

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 5 years ago.
Improve this question
I simply would like to initizlize an unordered_map with a vector.
When I have tried the code below, the code does not compile.
What is the shortest syntax to initilize unordered_map with a vector? How would you implement following method without using loop.
unordered_map<int, int> convertToMap(const vector<int>& v)
{
unordered_map<int, int> umap(v.begin(), v.end());
return umap;
}
I have found some resources, and I have tried to initialize through a range, but it does not worked either!
initialize-unordered-map
How to initialize unordered_map with vector?
If your vector contains pairs of elements, so that one could be interpreted as key and one as value then you can use range initialization:
#include <vector>
#include <unordered_map>
#include <iostream>
#include <utility>
int main()
{
std::vector<std::pair<int, int>> v = { {1,10}, {2,20}, {3,30} };
std::unordered_map<int, int> map(v.begin(), v.end());
std::cout << map[2] << std::endl;
return 0;
}
The above prints: 20

Map size different from expected value after adding values to the map [closed]

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 7 years ago.
Improve this question
Basically I have a edgeCostMap of type
map<pair<int, float>, int>
and a vector of 42 vertices. I loop through the vector of vertices and add values to the map as follows:
for(int vertexIndex = 0; vertexIndex < V.size(); vertexIndex++)
{
pair<int, float> toAdd;
toAdd.first = vertexIndex;
toAdd.second = V[vertexIndex].edgeCollapseCost;
edgeCostMap[toAdd] = vertexIndex;
}
However after the loop has been finished and I print out the map contents as follows:
for(map<pair<int, float> ,int>::iterator it = edgeCostMap.begin(); it != edgeCostMap.end(); it++)
{
logFile<<"Vertex "<<it->second<<" has cost "<<it->first.second<<" has "<<mapVF[it->second].size()<<"neighbors"<<endl;
}
I only get back 12 statements. Is my mapping done incorrectly?
Compare function:
class comparator {
public:
bool operator()(const std::pair<int, float>& a, const std::pair<int, float>& b) const {
return a.second < b.second;
}
};
Your comparator considers two keys equal (neither less than the other) if their floats are equal. You cannot put two equal keys in a map. You probably want to use the default comparator but put the float first in the set. This will sort first on the float and second on the integer, ensuring the keys are not equal if their integers differ.

Trying to create a function that will join words together from two unevenly sized vectors of strings [closed]

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;
}