How to create graph from vertex? - c++

I have a list of connected vertexes.
My question is how to create and store a graph that represents this list?.
For example for
5
2 4 5
1 3 4
2 4 5
1 2 3 5
1 3 4
1 is connected to 2, 4, 5
2 -> 1, 3, 4
and so on..
Here is 2 (the same) representations.
And my second question is how to get all representations of that graph (in this image i showed 2, that are the same)
For one list of vertexes exists only one graphical represantation? if more, how to get all of that?
in image they are the same, differente drawings.

5 means how many lines
1 > 2, 4, 5
2 > 1, 3, 4
3 > 2, 4, 5
4 > 1, 2, 3, 5
5 > 1, 3, 4
(I am silly so I needed to type this in notepad).
#include <stdio.h>
class Cl_Graph;
class Cl_Chain;
class Cl_Vertex
{
friend Cl_Graph;
private:
Cl_Chain* mp_linkedTo;
Cl_Vertex();
void f_addLink(Cl_Vertex* in_link);
};
Cl_Vertex::Cl_Vertex()
{
mp_linkedTo= NULL;
}
class Cl_Graph
{
private:
int m_size;
Cl_Vertex* pm_vertexTable;
public:
Cl_Graph(int in_size);
void f_addLink(int in_index, int in_linkWith);
};
Cl_Graph::Cl_Graph(int in_size)
{
pm_vertexTable= new Cl_Vertex[m_size= in_size];
}
void Cl_Graph::f_addLink(int in_index, int in_linkWith)
{
if (in_index< m_size && in_linkWith< m_size)
{
pm_vertexTable[in_index].f_addLink(pm_vertexTable[in_linkWith]);
}
}
int main(int argc, char** argv)
{
Cl_Graph graph(5);
graph.f_addLink(1, 2);
graph.f_addLink(1, 4);
graph.f_addLink(1, 5);
// ...
return 0;
}
You can start with something like this. You can even type a function that would get a chain of vertexes as argument to add to graph, and instead of the array it can have a chain of link chains :p good luck!

Related

C++ 2D Vector initialization with another vector

vector<vector<double>> weights
{
{1},
{1}
};
Above is my code to make a 2x1 vector each holding 1.
I would like to make a matrix of 2xN that I could use to multiply with that vector.
I have seen other stackoverflow questions that talk about creating matrices, and most of the ones I've seen are with fixed values, or user input.
But what I would like to do, is initialize the entire first column of N length with 1s, and the initialize the entire second column with a second vector I already have.
I am unsure how in C++ I could accomplish this. I'm way more familiar with R, and in R this is a pretty simple task. Any thoughts or guidance?
You mean like this?
std::vector<int> vinner {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
std::vector<std::vector<int>> v {
std::vector<int>(10, 1),
vinner
};
int main(int argc, char **argv)
{
for (auto i : v) {
for (auto j : i) {
std::cout << j << " ";
}
std::cout << "\n";
}
return 0;
}
Output:
$ clang++ -o vect vect.cpp -std=c++17
$ ./vect
1 1 1 1 1 1 1 1 1 1
1 2 3 4 5 6 7 8 9 10

Efficient way to enumerate unique undirected paths

Given a subset of nodes {1,2,...,N} is there any STL or boost function that returns unique undirected tours over all of them?
std::next_permutation() gives all N! directed tours, where 1-2-...-N is different from N-N-1-...-2-1.
However, in this case, I don't want both of them, but only one of them. Essentially, I would like to enumerate only N! / 2 of the tours.
The following code that uses std::next_permutation() and unordered_set works, but is there anything more efficient? The following code essentially generates all N! directed tours and discards half of them after checking against an unordered_set().
#include <vector>
#include <unordered_set>
#include <algorithm>
#include <boost/functional/hash.hpp>
template <typename T, typename U> bool unorderedset_val_there_already_add_if_not(std::unordered_set<T, U>& uos, T& val) {
if (uos.find(val) != uos.end())
return true;//val already there
uos.insert(val);
return false;//Value is new.
}
int main() {
std::vector<int> sequence{ 1, 2, 3};
std::unordered_set<std::vector<int>, boost::hash<std::vector<int>>> uos;
do {
printf("Considering ");
for (std::size_t i = 0; i < sequence.size(); i++)
printf("%d ", sequence[i]);
printf("\n");
std::vector<int> rev_sequence = sequence;
std::reverse(rev_sequence.begin(), rev_sequence.end());
if (unorderedset_val_there_already_add_if_not(uos, sequence) || unorderedset_val_there_already_add_if_not(uos, rev_sequence)) {
printf("Already there by itself or its reverse.\n");
}
else {
printf("Sequence and its reverse are new.\n");
}
} while (std::next_permutation(sequence.begin(), sequence.end()));
getchar();
}
That is, given {1,2,3}, I only want to enumerate (1-2-3), (1-3-2) and (2-1-3). The other three permutations (2-3-1), (3-1-2) and (3-2-1) should not be enumerated because their reverse sequence have already been enumerated.
If you want to stay with next_permutation rather than make own generator routine, the simplest way is filter out a half of permutation with some condition.
Very simple one: the last element should be larger than the first one.
#include <vector>
#include <algorithm>
#include "stdio.h"
int main() {
std::vector<int> sequence{ 1, 2, 3, 4};
do {
if (sequence[sequence.size()-1] > sequence[0]) {
for (std::size_t i = 0; i < sequence.size(); i++)
printf("%d ", sequence[i]);
printf("\n");
}
} while (std::next_permutation(sequence.begin(), sequence.end()));
getchar();
}
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 4 1 3
3 1 2 4
3 2 1 4
Possible own implementation:
Generate all pairs (start; end) where start < end
Generate all permutations of `n-2` values without start and end
For every permutation make {start, permutation.., end}
1 ... 2 + permutations of {3, 4}
1 3 4 2
1 4 3 2
1 ... 3 + permutations of {2,4}
1 2 4 3
1 4 2 3
...
3 ... 4 + permutations of {1, 2}
3 1 2 4
3 2 1 4
...

storing a 2D array into a 2D vector in c++

Suppose I have a following 2D matrix in the following format. First line indicates the dimension and the rest other lines contains the elements. In this case it's a 6*6 Matrix:
6
1 2 3 4 2 3
3 3 4 5 2 1
4 3 3 1 2 3
5 4 3 6 2 1
3 2 4 3 4 3
2 3 4 1 5 6
Normally we can store the matrix in a vector using this:
typedef std::vector<int32_t> vec_1d;
typedef std::vector<vec_1d> vec_2d;
vec_2d array{
{ 1, 2, 3, 4, 2, 3 }
, { 3, 3, 4, 5, 2, 1 }
, { 4, 3, 3, 1, 2, 3 }
, { 5, 4, 3, 6, 2, 1 }
, { 3, 2, 4, 3, 4, 3 }
, { 2, 3, 4, 1, 5, 6 }
};
But if I want to take this array in the format I have shown above from a text file into a 2d vector like the above one, how will I do this in c++ ?
This should work:
#include "fstream"
#include "vector"
using namespace std;
int main()
{
ifstream fin("file.txt");
int n;
fin >> n;
vector < vector <int> > matrix (n, vector <int>(n));
// or vec_2d matrix (n, vec_1d(n)); with your typedefs
for (auto &i: matrix)
for (auto &j: i)
fin >> j;
}

Maps and Vectors -STL in C++

Can anyone explain this code working?It is to find index of 2 elements in vector that add to produce the given target.I don't understand how STL works in this.
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int>m;
vector<int>v;
if(nums.size()==0)
{
return v;
}
for(int i=0;i<nums.size();i++)
{
if(m.find(nums[i])==m.end())
{
m[target-nums[i]]=i+1;
}
else
{
v.push_back(m[nums[i]]);
v.push_back(i+1);
}
}
return v;
}
};
It's pretty easy. Say the vector is { 8, 4, 3, 2, 5 } and the target is 10. First number you find is 8, so now you know that you are looking for a 2 (because 8 + 2 is 10). So you add the new target 2 and the index of 8 (which is 1 because the indexes are 1 based) to the map. Next number is 4 so now you are looking for 6, so 6 and the index 2 get added to the map. Now the map looks like this
2 ==> 1
6 ==> 2
Eventually you'll find one of the targets in the map (in this case we'll find a two), the map gives us the index of the original 8, and we know the index of the 2 because we've just found it, so we can output both indexes.
The code could be improved, but I think it works.

Regarding vector values

Here is a code snippet below.
Input to program is
dimension d[] = {{4, 6, 7}, {1, 2, 3}, {4, 5, 6}, {10, 12, 32}};
PVecDim vecdim(new VecDim());
for (int i=0;i<sizeof(d)/sizeof(d[0]); ++i) {
vecdim->push_back(&d[i]);
}
getModList(vecdim);
Program:
class dimension;
typedef shared_ptr<vector<dimension*> > PVecDim;
typedef vector<dimension*> VecDim;
typedef vector<dimension*>::iterator VecDimIter;
struct dimension {
int height, width, length;
dimension(int h, int w, int l) : height(h), width(w), length(l) {
}
};
PVecDim getModList(PVecDim inList) {
PVecDim modList(new VecDim());
VecDimIter it;
for(it = inList->begin(); it!=inList->end(); ++it) {
dimension rot1((*it)->length, (*it)->width, (*it)->height);
dimension rot2((*it)->width, (*it)->height, (*it)->length);
cout<<"rot1 "<<rot1.height<<" "<<rot1.length<<" "<<rot1.width<<endl;
cout<<"rot2 "<<rot2.height<<" "<<rot2.length<<" "<<rot2.width<<endl;
modList->push_back(*it);
modList->push_back(&rot1);
modList->push_back(&rot2);
for(int i=0;i < 3;++i) {
cout<<(*modList)[i]->height<<" "<<(*modList)[i]->length<<" "<<(*modList)[i]->width<<" "<<endl;
}
}
return modList;
}
What I see is that the values rot1 and rot2 actually overwrite previous values.
For example that cout statement prints as below for input values defined at top. Can someone tell me why are these values being overwritten?
rot1 7 4 6
rot2 6 7 4
4 7 6
7 4 6
6 7 4
rot1 3 1 2
rot2 2 3 1
4 7 6
3 1 2
2 3 1
You are storing pointers to local variables when you do this kind of thing:
modList->push_back(&rot1);
These get invalidated every loop cycle. You could save yourself a lot of trouble by not storing pointers in the first place.