This question might appear to be very stupid but I don't understand how to merge two sorted vectors with std::merge.
I tried some code using cplusplus reference.
struct t
{
t(int x):a(x){}
int a;
};
bool operator<(const t& p,const t&b)
{
return p.a<b.a;
}
int main()
{
vector<t> a,b,c;
a.push_back(t(10));
a.push_back(t(20));
a.push_back(t(30));
b.push_back(t(1));
b.push_back(t(50));
merge(a.begin(),a.end(),b.begin(),b.end(),c.begin());
return 0;
}
There is a segmentation fault with this code.
You will want to make sure c is big enough, or grows:
std::merge(a.begin(),a.end(),b.begin(),b.end(),std::back_inserter(c));
Alternatively:
c.resize(a.size() + b.size());
std::merge(a.begin(),a.end(),b.begin(),b.end(),c.begin());
See it Live On Coliru
#include <algorithm>
#include <vector>
#include <iterator>
struct t
{
t(int x):a(x){}
int a;
};
bool operator<(const t& p,const t&b)
{
return p.a<b.a;
}
int main()
{
std::vector<t> a,b,c;
a.push_back(t(10));
a.push_back(t(20));
a.push_back(t(30));
b.push_back(t(1));
b.push_back(t(50));
std::merge(a.begin(),a.end(),b.begin(),b.end(),std::back_inserter(c));
return 0;
}
Related
I have made a triplet using a class with all members as integers. I want to insert the triplet in min priority queue using STL in C++. I heard that it can be done using a bool comparator function, but don't have any idea about how to use it with 3 elements.
Note: I don't want to use vector pairs for inserting 3 values (I know how to do it ), I only want to use class triplets.
Can someone help me in implementing it?
using namespace std;
#include<bits/stdc++.h>
class triplet{
public:
int element;
int arrIndex;
int elementIndex;
};
priority_queue<triplet, vector<triplet>, greater<triplet>> pq;
I don`t know why you did std::vector, std::greater but.
#include <queue>
#include <vector>
class triplet {
public:
int element;
int arrIndex;
int elementIndex;
constexpr bool operator>(const triplet& r)
{
return element > r.element;
}
};
int main()
{
std::priority_queue<triplet, std::vector<triplet>, std::greater<>> queue;
triplet a, b;
a.element = 3;
b.element = 5;
queue.push(a);
queue.push(b);
}
This is possible by define a triplet operator.
or
#include <queue>
#include <vector>
class triplet {
public:
int element;
int arrIndex;
int elementIndex;
};
template <>
struct std::greater<triplet>
{
bool operator()(const triplet& l, const triplet& r)
{
return l.element > r.element;
}
};
int main()
{
std::priority_queue<triplet, std::vector<triplet>, std::greater<triplet>> queue;
triplet a, b;
a.element = 3;
b.element = 5;
queue.push(a);
queue.push(b);
}
through template specialization.
I would like to populate a set with a vector of tile objects, but I get an error.
#include <set>
#include <vector>
using namespace std;
struct tile
{
int value;
int suit;
};
tile makeTile(const int &a, const int &b)
{
tile t{a, b};
return t;
}
int main()
{
set<vector<tile>> s;
vector<tile> v;
v.push_back(makeTile(0, 0));
s.insert(v); // Error
return 0;
}
I don't get an error if I use integers rather than objects.
#include <set>
#include <vector>
using namespace std;
int main()
{
set<vector<int>> s;
vector<int> v;
v.push_back(0);
s.insert(v); // No error
return 0;
}
you can't make a set(actually ordered) of objects where logical operation is not possible.
But definitely you can make set by defining the logical operation by yourself. In programming sense, you can make set after doing some operator overloading.
Actually set is ordered set so you need to overload < operator for your struct.
Here is the code segment;
#include <iostream>
using namespace std;
struct tile{
int value;
int suit;
bool operator<(const tile& a);
};
tile makeTile(const int &a, const int &b)
{
tile t{a,b};
return t;
}
bool operator<(const tile& a, const tile& b){
return a.value <= b.value;
}
int main()
{
set<vector<tile> > s;
vector<tile> v;
v.push_back(makeTile(0,0));
v.push_back(makeTile(0,5));
v.push_back(makeTile(-1,5));
s.insert(v); // No Error here
}
if you want to check it then you can check it by following code:
for(auto &i:s){
for(auto &b:i){
cout << b.value << " " << b.suit << endl;
}
}
hope it will help.
The question is within the code snippet:
#include <algorithm>
#include <utility>
#include <iostream>
struct A {
static int max(std::pair<int, int> const& pair) {
return std::max(pair.first, pair.second);
}
int use_max(std::pair<int, int> const & p, int const i) {
// 1) The following works fine:
// return std::max(i, max(p));
// 2) The following also works fine:
// using std::max;
// return max(i, this->max(p));
// 3) This does not compile, afaiu cause the A::max did
// not even got into the overload resolution list due to
// name look up rules.
using std::max;
return max(i, max(p));
// Question: What do I write here to add A::max into the
// overload resolution list, e.g., something like:
// using std::max;
// using A::max;
// return max(i, max(p));
}
};
int main() {
std::cout << A().use_max(std::make_pair(2, 3), 1);
}
using A::max; is not possible since A is a class and not a namespace.
And the answer to your query is simple:
return max(i, A::max(p));
I am not sure what else are you hoping to achieve here.
Update: Thought about it some more and you can modify code this way?
#include <algorithm>
#include <utility>
#include <iostream>
struct B {
static int max(int A, int B)
{
return std::max(A,B);
}
};
struct A:B{
static int max(std::pair<int, int> const& pair) {
return std::max(pair.first, pair.second);
}
using B::max;
int use_max(std::pair<int, int> const & p, int const i) {
return max(i, max(p));
}
};
int main() {
std::cout << A().use_max(std::make_pair(2, 3), 1);
}
If you look at the code below, I am trying to create a priority_queue, I have named it DijkstraPriorityQueue, that has a custom comparator which also uses the private vector distTo.
You can see that I have some dots ....... as everything I tried have failed.
What is the cleanest solution (or possible solutions) to make this work as intended in this specific case ?
Dijkstra.h
class Dijkstra
{
public:
Dijkstra(Graph G, int s); // Create
~Dijkstra(); // Destroy
private:
bool compare(int u, int v)
{
return distTo[u] < distTo[v];
}
typedef priority_queue<int, vector<int>, .........> DijkstraPriorityQueue;
vector<float> distTo; // distTo[u] is the distance of the shortest s->u path
DijkstraPriorityQueue PQ; // Min-Priority Queue, implemented for Dijkstra
};
Dijkstra.cpp
Dijkstra::Dijkstra(Graph G, int s)
{
PQ = DijkstraPriorityQueue(...........);
}
Option #1
#include <functional>
#include <queue>
#include <vector>
class Dijkstra
{
public:
Dijkstra()
: PQ([this](int u, int v){ return distTo[u] < distTo[v]; })
{
}
private:
using DijkstraPriorityQueue
= std::priority_queue<int, std::vector<int>, std::function<bool(int,int)>>;
std::vector<float> distTo;
DijkstraPriorityQueue PQ;
};
Option #2
#include <functional>
#include <queue>
#include <vector>
class Dijkstra
{
public:
Dijkstra()
: PQ(std::bind(&Dijkstra::compare, this, std::placeholders::_1, std::placeholders::_2))
// or
// : PQ([this](int u, int v){ return compare(u, v); })
{
}
private:
bool compare(int u, int v) const
{
return distTo[u] < distTo[v];
}
using DijkstraPriorityQueue
= std::priority_queue<int, std::vector<int>, std::function<bool(int,int)>>;
std::vector<float> distTo;
DijkstraPriorityQueue PQ;
};
Option #3
(For the record, if you are stuck with C++03):
#include <queue>
#include <vector>
class Dijkstra
{
public:
Dijkstra()
: PQ(compare(this))
{
}
private:
struct compare
{
explicit compare(Dijkstra* d) : d(d) {}
bool operator()(int u, int v) const
{
return d->distTo[u] < d->distTo[v];
}
const Dijkstra* d;
};
typedef std::priority_queue<int, std::vector<int>, compare> DijkstraPriorityQueue;
std::vector<float> distTo;
DijkstraPriorityQueue PQ;
};
Is it possible to write const function with apply_visitor inside?
For example, this code compiles without errors:
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <boost/variant.hpp>
using namespace std;
typedef boost::variant<int,string> vTypeVariants;
struct vType_toN : boost::static_visitor<int>
{
int operator()(int& i) const {
return i;
}
int operator()(const string& str) const{
return str.length();
}
};
class vType{
public:
vType(const int& src) : data(src){}
vType(const std::string& src) : data(src){}
int getLength(){
return boost::apply_visitor(vType_toN(),data);
}
private:
vTypeVariants data;
};
int main(int argc, char ** argv)
{
vType x = string("2");
printf("L=%d",x.getLength());
return(0);
}
Unless you will add const to getLength():
int getLength() const{
return boost::apply_visitor(vType_toN(),data);
}
In such case an error with vast description (2 pages) appears complaining about problem with initializing first argument.
So, the question is: How to use apply_visitor inside const function?
Found out myself.
Forgot const before int in static_visitor class operator definition.
Maybe someone will find this useful as it was not easy to find this out (my original class is much bigger).