Iterate through 2d vector - c++

I try to create a Graph class and want to print all Edges to the screen. But I have a problem iterating a 2d vector.
class Graph
{
public:
Graph(void);
~Graph(void);
vector<Node*> nodes;
void addNode(Node node);
void addDirectedEdge(Node &head,Node* tail,int cost);
void toSrceen();
};
class Node
{
public:
Node(char* name);
~Node(void);
char* name;
vector<Node*> children;
vector<int> costs;
};
void Graph::toSrceen()
{
for (vector<vector<Node*>>::iterator i = nodes.begin(); i != nodes.end();++i)
{
for (vector<Node*>::iterator j = i->begin(); j != i->end();++i)
{
cout << j->name;
}
}
}
There is a problem in the first for loop but i can not find the mistake...

It looks like the inner loop increments the wrong iterator. Probably needs to be:
for (vector<Node*>::iterator j = i->begin(); j != i->end();++j)

You're incrementing "i" each iteration of the second loop rather than j.

vector<vector<Node*>>::iterator i = nodes.begin()
if you look at the declaration of Graph::nodes, it's a vector<Node*>, not a vector<vector<Node*>>
the loop should probably be something like:
void Graph::toSrceen()
{
for (vector<Node*>::iterator i = nodes.begin(); i != nodes.end();++i)
{
Node* currNode = *i;
for (vector<Node*>::iterator j = currNode->children.begin(); j != currNode->children.end();++j)
{
cout << j->name;
}
}
}

Related

How to fix segmentation fault with two-dimensional nested vectors

I have written one simple graph Adj Matrix from one Adj List from gitHub .
The first one is Adj list,
Second is Adj matrix.
The first One work well. But the second is wrong with int Num which represent the vertices number like the first one int numOfVertices.
It seed like the 'int Num' become a read only variable. It crash into Process finished with exit code 11 .
I have looked for wiki to find "segmentation default", there are 4 reasons , one of them is trying to modify a read only
variable.
Then I cancel the modify for "Num" in constructor for the Adj Matrix. It work well.
But I don't know why the first one is well but the second is wrong? And how to solve it? Because I need to modify the value of Num...
The Adj List code
#ifndef ALTHGORITHM_GRAPH_ADJ_LIST_H
#define ALTHGORITHM_GRAPH_ADJ_LIST_H
#include <iostream>
#include <vector>
#include <queue>
namespace graph_adj_list {
template <class dataType> // Type of data vertex will hold
class Graph {
int numOfVertices; // number of vertices.
struct Vertex; // forward declaration of vertex structure
struct Node { // linkedlist for mapping edges in the graph
Vertex * vertexPtr; // points to the vertex to which the edge is adjecent
Node * next; // points to the next edge belonging to same vertex
};
enum visitedState{ // Enum representing visited state of vertex
WHITE, // not yet visited
GRAY, // being visited
BLACK // visited
};
struct Vertex {
visitedState state; // state of vertex, visited/being visited/done
dataType data; // the template data
Node * list; // Pointer to all edges (linkedlist)
};
std::vector<Vertex> vertices; // vector of all vertices.
//private methods
Node * getNode( Vertex * ); // allocate and initialize a newnode for the adj list.
void insertAtEnd( Node * & , Vertex * ); // insert at the end of adjacency list of vertex.
void deleteAllAfter( Node * ); // delete the adjacency list of the vertex.
public:
Graph() = default; // Default constructor
Graph(std::vector<dataType> &);
~Graph();
}
template <typename dataType>
typename Graph<dataType>::Node *
Graph<dataType>::getNode(Vertex * v) // allocate and initialize a newnode for the adj list.
{
Node * newNode = new Node;
newNode->vertexPtr = v;
newNode->next = nullptr;
return newNode;
}
template <typename dataType>
void Graph<dataType>::insertAtEnd( Node * & node, Vertex * v) // insert at the end of adjacency list of vertex.
{
Node *newNode = getNode(v);
if ( node == nullptr ) {
node = newNode;
} else {
Node * temp = node;
while( temp->next != nullptr ) {
temp = temp->next;
}
temp->next = newNode;
}
}
template <typename dataType>
void Graph<dataType>::deleteAllAfter( Node * node ) // delete the adjacency list of the vertex.
{
Node * nextNode;
while( node != nullptr ) {
nextNode = node->next;
delete(node);
node = nextNode;
}
}
template <typename dataType>
Graph<dataType>::Graph(std::vector<dataType> & values) // Non default constructor, takes a vector of vertices data
: numOfVertices(values.size()),
vertices(numOfVertices)
{
for ( int i = 0; i < numOfVertices; ++i ) {
vertices[i].data = values[i];
vertices[i].list = nullptr;
vertices[i].state = WHITE;
}
}
template <typename dataType>
Graph<dataType>::~Graph()
{
for( int i = 0; i < numOfVertices; ++i ) {
deleteAllAfter(vertices[i].list);
}
}
} //end of namespace graph
The Adj Matrix code
#ifndef ALTHGORITHM_GRAPH_ADJ_MATRIX_H
#define ALTHGORITHM_GRAPH_ADJ_MATRIX_H
#include <iostream>
#include <vector>
namespace graph_adj_matrix {
template<typename T>
class Graph {
int Num ;
enum visitedState {
NO_VISIT,
VISITING,
VISITED
};
struct vertex {
T data;
visitedState state;
};
std::vector<std::vector<int>> Matrix;
std::vector<vertex> matrix_list;
public:
Graph() = default;
Graph(std::vector<T> &);
~Graph();
void setMatrix(size_t index1, size_t index2);
void display();
};
template<typename T>
Graph<T>::Graph(std::vector<T> &values) :
Num(values.size())
,matrix_list(Num){
for (typename std::vector<T>::size_type i = 0; i < Num; ++i)
{
matrix_list[i].data = values[i];
matrix_list[i].state = NO_VISIT;
}
for (typename std::vector<T>::size_type i = 0; i < Num; ++i)
for (typename std::vector<T>::size_type j = 0; j < Num; ++j)
Matrix[i].push_back(0);
}
template<typename T>
void Graph<T>::setMatrix(size_t index1, size_t index2) {
for (size_t i = 0; i < Num; ++i) {
if (i == index1 || i == index2) {
for (size_t j = 0; j < Num; ++j) {
if (((i == index1) && (j == index2)) || ((i == index2) && (j == index1))) {
Matrix[i][j] = 1;
break;
}
}
break;
}
}
}
template<typename T>
void Graph<T>::display() {
for (size_t i = 0; i < Num; ++i) {
for (size_t j = 0; j < Num; j++)
std::cout << Matrix[i][j] << " ";
std::cout << std::endl;
}
}
template <typename T>
Graph<T>::~Graph() {}
}
#endif //ALTHGORITHM_GRAPH_ADJ_MATRIX_H
Cpp:
#include "Graph_Adj_List.h"
#include "Graph_Adj_Matrix.h"
int main() {
std::vector<std::string> myVec{"ABC","DEF","GHI","ZZZ"};
graph_adj_list::Graph<std::string> myGraph(myVec);
graph_adj_matrix::Graph<std::string> myGraph_matrix(myVec);
}
I have debugger the program
graph_adj_list::Graph<std::string> myGraph(myVec);
work well.
But the
graph_adj_matrix::Graph<std::string> myGraph_matrix(myVec);
stop at
#ifndef _LIBCPP_CXX03_LANG
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
vector<_Tp, _Allocator>::push_back(value_type&& __x)
{
if (this->__end_ < this->__end_cap())
{
__RAII_IncreaseAnnotator __annotator(*this);
__alloc_traits::construct(this->__alloc(),
_VSTD::__to_raw_pointer(this->__end_),
_VSTD::move(__x));
__annotator.__done();
++this->__end_;
}
else
__push_back_slow_path(_VSTD::move(__x));
}
A function from vector header Row from 1635 to 1653.
Debugger report this
Exception = EXC_BAD_ACCESS (code=1, address=0x8)
this = {std::_11::vector<int,std::_1::allocator> * |0x0 } NULL
When I enter the body that sets the ```Matrix[i].push_back(0)''' It crashes the wrong condition.
The following is just an gues, after short playing around with your code:
Process finished with exit code 11
Probably could mean that your program encountered signal 11 (SIGSEGV, aka Segmentation fault)
My guess: you forgot to initialize Matrix, so Matrix[i].push_back(0); causes undefined behaviour and luckily resultet in a segmentation fault.
Edit: you can easily initialize the inner vectors with the vector constructor: std::vector<std::vector<int>>(Num, std::vector<int>(Num));. This will create a vector with Num copies of a vector with Num ints.
After having fixed the problem that #churill proposed:
I haven't compiled your code, but I think the problem lies on these lines:
Matrix[i][j] = 1;
In this case Matrix[i] is a vector<int>, but you never reserve capacity for it, so Matrix[i][j] is writing to protected / unallocated memory, causing the segfault.
Initialize your "internal" vectors (all Matrix[i]) with sufficient capacity and see if that resolves your segfault.

Autocomplete using Trie

I'm attempting to make some sort of autocomplete feature in c++. First by using a Trie and once that works (and most importantly, I know HOW it all works) I'll try it using a Ternary tree. But as for now I get a segmentation fault when ever I add words starting with a different characte than those already in the Trie.
Eg. we add "abc", "abcd" and "abcde" this is no problem. Later when I want to add (while the "abc" etc are still in the Trie) "xfce", "xfced" a segmentation fault occurs.
I've been debugging this for some while now and can't seem to find the problem.
I think the problem resides somewhere in Trie.cpp so that's the file I'll provide here. However it might be in the main function aswell but I don't wanna get yelled at for posting to much code...
#include "Trie.h"
#include <iostream>
Trie::Trie()
{
this->root = new Node(false);
}
Trie::~Trie()
{
}
Trie::Node::Node(bool isLeaf)
{
this->isLeaf = isLeaf;
}
void Trie::insert(const std::string& word)
{
Node* crawler = this->root;
int index;
for(int i = 0; i < word.length(); ++i)
{
index = CHAR_TO_INDEX(word.at(i));
if(!crawler->children[index])
{
crawler->children[index] = new Node(false);
}
crawler = crawler->children[index];
}
crawler->isLeaf = true;
}
int Trie::contains(const std::string& word)
{
int index;
Node* crawler = this->root;
for(int i = 0; i < word.length(); ++i)
{
index = CHAR_TO_INDEX(word.at(i));
if(!crawler->children[index])
{
return -1;
}
crawler = crawler->children[index];
}
return (crawler != NULL && crawler->isLeaf);
}
std::vector<std::string> Trie::possibleSuffixes(std::string& prefix)
{
Node* crawler = this->root;
int index;
std::vector<std::string> result;
for(int i = 0; i < prefix.length(); ++i)
{
index = CHAR_TO_INDEX(prefix.at(i));
crawler = crawler->children[index];
}
traverse(prefix, crawler, result);
return result;
}
void Trie::traverse(std::string prefix, Node* node, std::vector<std::string>& v)
{
if(node->isLeaf)
{
v.push_back(prefix);
}
for(int i = 0; i < ALPHABET; ++i)
{
if(node->children[i])
{
traverse(prefix + (char)('a' + i), node->children[i], v);
}
}
}
Entire Trie class:
#ifndef TRIE_H
#define TRIE_H
#include <string>
#include <vector>
#define ARRAYSIZE(a) sizeof(a / sizeof(a[0]))
#define ALPHABET 26
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')
class Trie
{
private:
struct Node
{
Node(bool isLeaf);
struct Node *children[ALPHABET];
bool isLeaf;
};
Node *root;
void traverse(std::string prefix, Node* node, std::vector<std::string>& v);
public:
Trie();
~Trie();
int contains(const std::string& word); //Checks the existance of a specific word in the trie
void insert(const std::string& word); //Inserts new word in the trie if not already there
std::vector<std::string> possibleSuffixes(std::string& prefix);
};
Though you didn't mention about your Node class, I am assuming this -
class Node {
public:
bool isLeaf;
// must be >= 25 as you're inserting lowercase letters
// assuming your CHAR_TO_INDEX(ch) returns 0 based index
// e.g. 'a' => 0, 'b' => 1 ... 'z' => 25
Node* children[30];
// default constructor should be like this
Node(): isLeaf(false) {
for(int i = 0; i < 26; i++) {
children[i] = NULL;
}
}
~Node() {
for(int i = 0; i < 26; i++) {
if(children[i]) {
delete children[i];
children[i] = NULL;
}
}
delete this;
}
};
Please compare your Node class/struct whether its something like this.

Disjoint set data structure : track size of each tree

Below is my implementation to keep track of the size of each tree in the disjoint set forest.
Can you please tell me what is wrong with it ? I am trying to solve UVa problem https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3638
#include <iostream>
#include <cstdio>
#include <unordered_map>
using namespace std;
class Node {
public :
int id;
Node *parent;
unsigned long long rank;
Node(int id) {
this->id = id;
// this->data = data;
this->rank =1; //size here
this->parent = this;
}
friend class DisjointSet;
};
class DisjointSet {
unordered_map<int,Node*> nodesMap;
Node *find_set_helper(Node *aNode) {
if (aNode == aNode->parent) {
return aNode->parent;
}
return find_set_helper(aNode->parent);
}
void link(Node *xNode,Node *yNode) {
if( xNode->rank > yNode->rank) {
yNode->parent = xNode;
xNode->rank += yNode->rank;
}
// else if(xNode-> rank < yNode->rank){
// xNode->parent = yNode;
// yNode->rank += xNode->rank;
// }
else {
xNode->parent = yNode;
yNode->rank += xNode->rank;
}
}
public:
DisjointSet() {
}
void AddElements(int sz) {
for(int i=0;i<sz;i++)
this->make_set(i);
}
void make_set(int id) {
Node *aNode = new Node(id);
this->nodesMap.insert(make_pair(id,aNode));
}
void Union(int xId, int yId) {
Node *xNode = find_set(xId);
Node *yNode = find_set(yId);
if(xNode && yNode)
link(xNode,yNode);
}
Node* find_set(int id) {
unordered_map<int,Node*> :: iterator itr = this->nodesMap.find(id);
if(itr == this->nodesMap.end())
return NULL;
return this->find_set_helper(itr->second);
}
~DisjointSet(){
unordered_map<int,Node*>::iterator itr;
for(itr = nodesMap.begin(); itr != nodesMap.end(); itr++) {
delete (itr->second);
}
}
};
int main() {
int n,m,k,first,cur;
//freopen("in.in","r",stdin);
scanf("%d %d",&n,&m);
while(n != 0 || m != 0) {
DisjointSet *ds = new DisjointSet();
ds->AddElements(n); // 0 to n-1
//printf("\n n = %d m = %d",n,m);
for(int i=1;i<=m;i++) {
scanf("%d",&k);
//printf("\nk=%d",k);
if ( k > 0 ) {
scanf("%d",&first);
for(int j=2;j<=k;j++) {
scanf("%d",&cur);
ds->Union(first,cur);
}
}
}
Node *zeroSet = ds->find_set(0);
// unsigned long long count = ds->getCount(zeroSet->id);
printf("%llu\n",zeroSet->rank);
delete ds;
scanf("%d %d",&n,&m);
}
return 0;
}
The link function in the above code does the job of updating the tree size.
The solution to the problem is to find the set which elements 0 belongs to and get the size of the representative element of the set.
But I am getting wrong answer with this code.
Can you please help me
In your Union function, check if both nodes are already in the same set.
if(xNode && yNode && xNode != yNode)
link(xNode,yNode);

Sorting a queue - C/C++

I have created a queue that in each node there are three information. I want to create a member function in class that sorts the queue when called. I wish to have the queue sorted by time? (it is an int and a member of q_node). This queue needs to be sorted in such a way that the lowest value of 'time' is in the front and it is sorted in increasing order.
My code for my Queue is found below:
typedef struct Qnode{
int time;
char name[10];
char value;
struct Qnode *q_next;
struct Qnode *q_prev;
} q_node;
class Queue{
private:
q_node *q_rear;
q_node *q_front;
int number;
public:
Queue();
void enqueue(int time, char *s, char value);
q_node *q_top(){
return q_front;
}
void dequeue();
void display();
void queueSort();
bool isEmpty();
};
Queue::Queue(){
q_rear = NULL;
q_front = NULL;
number = 0;
}
bool Queue::isEmpty(){
if (q_front == NULL)
return true;
else
return false;
}
void Queue::enqueue(int t, char *n, char v){
q_node *q_temp = new q_node;
q_temp->time = t;
strcpy(q_temp->name , n);
q_temp->value = v;
q_temp->q_next = NULL;
if(q_front == NULL){
q_front = q_temp;
}
else{
q_rear->q_next = q_temp;
}
q_rear = q_temp;
number++;
}
void Queue::dequeue(){
q_node *q_temp = new q_node;
q_temp = q_front;
q_front = q_front -> q_next;
number--;
delete q_temp;
}
void Queue::display(){
q_node *p = new q_node;
p = q_front;
while(p!=NULL){
cout<< "\ntime: " << p->time;
cout<< "\nname: " << p->name;
cout<< "\nvalue: " << p->value;
cout << endl;
p = p->q_next;
}
}
void Queue::queueSort(){
//Code for sorting
}
One way is to dump the queue into an array or vector by using dequeue, use std::sort and then rebuild the queue from scratch by using your enqueue function. This is clean and avoids messing up with pointers. This is also optimal because running time is dominated by time it takes to sort.
Something like:
v = vector of nodes
while(Q.isEmpty() == false)
{ v.push_back(*Q.top());
Q.dequeue();
}
sort(v.begin(), v.end(), cmp);
for(int i = 0; i < v.size(); i++)
{ Q.enqueue(v[i].time, v[i].name, v[i].value);
}
Where cmp compares nodes by time.
Find the node with the smallest time field, remove it from the list and make it the head of a new list. Then continue to do this, appending the nodes to the new list, in a loop while the original list is not empty. When the original list is empty, take the new (sorted) list and make it the new queue.
It might not be especially efficient, but should work fine.

Check if vector item not null C++

I have structure:
struct node
{
bool data;
node* l;
node* r;
node(bool data_) : data(data_), l(0), r(0) {}
};
And loop like this
void printNode(std::vector<node*> nodes, int level, int max_level)
{
for (int i = 0; i < nodes.size(); i++) {
node * itr = nodes.at(i);
if (itr->data != 2) {
cout << itr->data;
newNodes.push_back(itr->l);
newNodes.push_back(itr->r);
} else {
newNodes.push_back(new node(2));
newNodes.push_back(new node(2));
cout << " ";
}
printWhitespaces(betweenSpaces);
}
}
Some times itr->l(or r) is null, not init struct. How i can check this ?
Something like this? It will skip your NULL elements, and elements with NULL value for r member of the vector and continue the for loop.
node * itr = nodes.at(i);
if(!itr || !itr->r) continue;
To check if a pointer is null simply use:
itr->l == 0
If it is 0 it is null. But consider using smart pointers, they are much safer.
You should also considering iterating over your vector the standard way, using something like this:
std::vectoc<node*>::iterator
it = nodes.begin(),
ite = nodes.end();
for(; it != ite; ++it) {
...
}
And finally you should probably be passing your vector by reference like this:
void printNode(std::vector<node*>& nodes, int level, int max_level)