So I'm trying to call on my list of Edge*s called edgelist. I have a graph.cpp below that is supposed to display an adjacency list of the graph.
#include <sstream>
#include <fstream>
#include <iostream>
#include <string>
#include <list>
#include "Graph.hpp"
Graph::Graph(){}
void Graph::displayGraph(){
for(int i = 0; i < vertices[vertices.size()-1].label; i++){
cout << vertices[i].label << ": ";
for(int j = 0; j <= edgeList.size(); j++){
if(edgeList[j].start==i){
cout << edgeList[j].end;
}
}
}
}
Graph.hpp includes Vertex.hpp which is below.
#ifndef Vertex_hpp
#define Vertex_hpp
#include <stdio.h>
#include <list>
#include <string>
#include <vector>
#include "Edge.hpp"
using namespace std;
class Vertex {
public:
// the label of this vertex
int label;
// using a linked-list to manage its edges which offers O(c) insertion
list<Edge*> edgeList;
// init your vertex here
Vertex(int label);
// connect this vertex to a specific vertex (adding edge)
void connectTo(int end);
};
#endif /* Vertex_hpp */
Yet, when I run my code I get an error saying that edgeList is not declared in this scope.
In Graph::displayGraph(), you are iterating on a list of Vertexs. To access the edgeList field from an object, you need to reference it as such. See the following code:
void Graph::displayGraph(){
for(int i = 0; i < vertices[vertices.size()-1].label; i++){
cout << vertices[i].label << ": ";
for(int j = 0; j <= vertices[i].edgeList.size(); j++){
if(vertices[i].edgeList[j].start==i){
cout << vertices[i].edgeList[j].end;
}
}
}
}
Related
Im trying to create a adjacency representation of a graph.
I wrote a small program using vectors of vectors , however I keep getting "segmentation fault" but the compiler(clang++ version 5.0.1 on Windows) it seems wereever I try to access the vector vertex_matrix its giving a segmentation fault, why is it not being instantiated?
Here is the header:
#ifndef GRAPH_MATRIX
#define GRAPH_MATRIX
#include <vector>
//header for graph represented via adjacency matrix with minimal functionality
class graph
{
public:
graph(int);
~graph();
void add_edge(int v1, int v2, int weight);
void print_graph();
private:
std::vector<std::vector<int>> vertex_matrix;
int num_of_vertices;
int num_of_edges;
};
#endif
Here is the cpp implementation:
#include <iostream>
#include "graph_matrix.h"
#include <climits>
using namespace std;
//header for graph represented via adjacency matrix with minimal functionality
graph::graph(int _num_of_vertices) : num_of_vertices(_num_of_vertices)
{
if (_num_of_vertices==0)
{
_num_of_vertices=10;
}
for (int i = 0; i < _num_of_vertices; i++)
{
vertex_matrix[i]=(vector<int> (_num_of_vertices,INT_MAX));
}
}
graph::~graph()
{
vertex_matrix.clear();
}
void graph::add_edge(int v1, int v2, int weight)
{
//vertex_matrix[v1-1][v2-1] == INT_MAX
vector<int> columnVector = vertex_matrix[v1-1];
if (columnVector[v2-1] == INT_MAX)
{
columnVector[v2-1] = weight;
}
}
void graph::print_graph()
{
cout << "vertex_matrix size:" << vertex_matrix.size() << endl;
for (int i=0; i< num_of_vertices; i++)
{
for (int j = 0; j < num_of_vertices; j++)
{
//vertex_matrix[i][j]
std::vector<int> columnVector = vertex_matrix[i];
if (columnVector[j] != INT_MAX)
{
std::cout << columnVector[j] ;
}
else
{
std::cout << "0";
}
}
std::cout << endl;
}//end for printing
}
Here is the main entry:
#include <iostream>
#include "graph_matrix.h"
using namespace std;
int main ()
{
std::cout << " Matrix representation of graph" << std::endl;
graph _graph(4);
_graph.add_edge(1,2,1);
_graph.add_edge(2,3,1);
_graph.add_edge(3,1,1);
_graph.add_edge(3,3,1);
_graph.add_edge(3,4,1);
_graph.add_edge(4,0,0);
_graph.print_graph();
}
I edited the above code to use pass by reference, however the matrix still prints as 0's.
Please help with pass by reference, updates below:
Header:
#ifndef GRAPH_MATRIX
#define GRAPH_MATRIX
#include <vector>
//header for graph represented via adjacency matrix with minimal functionality
class graph
{
public:
graph(int);
~graph();
void add_edge(int v1, int v2, int weight,std::vector<std::vector<int>> & matrix);
void print_graph();
std::vector<std::vector<int>> vertex_matrix;
private:
int num_of_vertices;
int num_of_edges;
};
#endif
Cpp file:
#include <iostream>
#include "graph_matrix.h"
#include <climits>
using namespace std;
//header for graph represented via adjacency matrix with minimal functionality
graph::graph(int _num_of_vertices) : num_of_vertices(_num_of_vertices) {
if (num_of_vertices == 0) {
num_of_vertices = 10;
}
for (int i = 0; i < num_of_vertices; i++) {
std::vector<std::vector<int>>& matrix = vertex_matrix;
matrix.push_back(vector<int> (num_of_vertices, INT_MAX));
}
}
graph::~graph() {
std::vector<std::vector<int>>& matrix = vertex_matrix;
matrix.clear();
}
void graph::add_edge(int v1, int v2, int weight,std::vector<std::vector<int>> & _matrix) {
//vertex_matrix[v1-1][v2-1] == INT_MAX
vector<int> columnVector = _matrix[v1 - 1];
if (columnVector[v2 - 1] == INT_MAX) {
columnVector[v2 - 1] = weight;
}
}
void graph::print_graph() {
std::vector<std::vector<int>>& matrix = vertex_matrix;
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix.size(); j++) {
//vertex_matrix[i][j]
std::vector<int> columnVector = matrix[i];
if (columnVector[j] != INT_MAX) {
std::cout << columnVector[j];
} else {
std::cout << "0";
}
}
std::cout << endl;
}//end for printing
}
main:
#include <iostream>
#include "graph_matrix.h"
using namespace std;
int main ()
{
std::cout << " Matrix representation of graph" << std::endl;
graph _graph(4);
std::vector<std::vector<int>>& m = _graph.vertex_matrix;
_graph.add_edge(1,2,1,m);
_graph.add_edge(2,3,1,m);
_graph.add_edge(3,1,1,m);
_graph.add_edge(3,3,1,m);
_graph.add_edge(3,4,1,m);
_graph.add_edge(4,0,0,m);
_graph.print_graph();
}
Any help will be appreciated.
Thanks
You create an empty vector and then try to access elements in it. Change your constructor to
graph::graph(size_t _num_of_vertices) :
vertex_matrix(
std::vector<std::vector<int>>(
_num_of_vertices,std::vector<int>(_num_of_vertices)
)
)
{}
to create a correctly sized vector.
Also in case _num_vertices == 0 you set it to 10 but thats after you initialized the member num_vertices so you leave the object in an inconsistent state. There are different ways to fix that, I would probably just throw an exception when the number of vertices passed is zero, or just ignore it. User wants a zero sized matrix? Why not?
Moreover the size should be unsigned not signed, there is size_t for container sizes. Even better you shouldnt have that member at all, because a vector already knows its size, the only reason to repeat that information is to introduce mistakes ;)
Apparently since its a segfault the C++ compiler won't output anything? I'm having some trouble with some C++ code I wrote. I'm a novice and I've been looking for this segfault for some time now... I can't figure it out.
My best guess is it is somewhere in the Deck() constructor, can anyone give me a hand?
Any help would be appreciated!
Thanks!
Follow up: In the future, does anyone have any good methods of debugging segfaults?
Deck.cpp
#include "Deck.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using std::ostream;
using std::vector;
const string Deck::RANKS[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
const string Deck::SUITS[4] = {"H","D","C","S"};
string cards[52];
int card = 0;
Deck::Deck() : size(0)
{
for (int i = 0; i < 13; i++)
{
for (int j = 0; j < 4; j++)
{
cards[size] = RANKS[i] + SUITS[j];
size++;
}
}
shuffle();
}
Deck::~Deck() {}
void Deck::shuffle()
{
size = MAX_SIZE;
std::random_shuffle(&cards[0], &cards[MAX_SIZE-1]);
}
string Deck::getCard()
{
card++;
return cards[card-1];
}
Deck.h
#ifndef DECK_H
#define DECK_H
#include <ostream>
#include <string>
#include <vector>
using std::ostream;
using std::string;
using std::vector;
class Deck
{
private:
static const int MAX_SIZE = 52;
static const string RANKS[13];
static const string SUITS[4];
static const string DECK[52];
int size;
public:
Deck();
~Deck();
void shuffle();
string getCard();
int getDeckSize() const {return size;}
friend ostream& operator<<(ostream&, const Deck&);
};
#endif
Main.cpp
#include <iostream>
#include "Deck.h"
using namespace std;
int main()
{
int pairs = 0;
for(int x = 0; x < 100; x++)
{
cout << "yep";
Deck deck;
cout << "awooga";
deck.shuffle();
cout << "hai";
string cards[2];
cards[0] = deck.getCard();
cards[1] = deck.getCard();
for(int y = 0; y < 5; y++)
{
string tempCard = deck.getCard();
if(cards[0].compare(tempCard) == 0 || cards[1].compare(tempCard) == 0)
{
pairs++;
}
}
}
cout << pairs;
return 0;
}
Your problem is that getCard has side effects, increasing the value of card every time you call it. As soon as you call it more than 52 times, your program may crash. Note that card is a global variable and doesn't reset to zero whenever you create a new deck.
I also noticed that your call to random_shuffle has an off-by-one error. The end iterator needs to be one beyond the actual end of your container, not pointing at the end (so it's a half-open range).
Finally for debugging segmentation faults in general, enable core dumps on your system and use gdb to attach the core to your binary. That will sometimes give you a good clue where to start.
I am getting a segmentation fault error after inserting an input file in this program I can't find where is the problem, could anyone help me with this?(it's the solution for the USACO training milk2 question).
#include <algorithm>
#include <bitset>
#include <limits>
#include <climits>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main ()
{
std::ifstream in ("milk2.in");
std::ofstream out ("milk2.out");
std::vector< pair <int,int> > v;
int n,i,maxn,maxs,t,ts;
in >> n;
for (i = 0; i < n; i++)
{
in >> v[i].first >> v[i].second;
}
for (i = 0; i < n; i++)
{
if (v[i].second<(v[i+1].first)
{
t=v[i+1].first-v[i].second;
if (t>maxn){
maxn=t;
}
}
else
{
ts=v[i+1].second-v[i].first;
if (ts>maxs)
{
maxs=ts;
}
}
}
out << maxs <<" "<< maxn;
return 0;
}
When you create the vector v, it's empty. So any index, even zero, will be illegal.
You need to first create the entries in the vector, e.g. by doing push_back.
This is my code
#include <stdio.h>
#include <cstdio>
#include <math.h>
#include <algorithm>
#include <set>
#include <struct.h>
#include <vector>
#include <functional>
using namespace std;
struct points {
int x,y;
};
bool operator<(const points &p1, const points &p2) {
return p1.x<p2.x;
};
vector<points> a(1000000);
int i,n,closest;
int main() {
scanf("%d\n",&n);
for (i=0; i<n-1; i++) {
scanf("%d %d\n",&a[i].x,&a[i].y);
}
sort(0,n-1,a);
return 0;
}
The errors that I get mostly state "Indirection requires pointer operand ('int' invalid). What could be wrong? I'm trying to sort the structs within the vector. I have used operator overload.
That's not how you use std::sort! Replace:
sort(0, n-1, a);
with:
sort(a.begin(), a.end());
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
struct points {
int x,y;
};
bool operator<(const points &p1, const points &p2) {
return p1.x<p2.x;
};
vector<points> a;
int i,n,closest;
int main() {
cin >> n;
for (i=0; i<n; i++) {
points p;
cin >> p.x >> p.y;
a.push_back(p);
}
sort(a.begin(), a.end());
for(i=0; i<n; i++)
cout << a[i].x << ',' << a[i].y << endl;
return 0;
}
I'm trying to do an insertion sort on a vector of baseball pitchers I created yesterday with help from a previous post. I want to sort the pitchers in ascending order by ERA1. I have gotten the insertion sort to work in the past for a set of integers. I think I have a syntax error in my code for the insertion sort. Up until trying to add the insertion sort this program was working well. I get an error - expected unqualified id before [ token. Thanks in advance for any help.
#ifndef Pitcher_H
#define Pitcher_H
#include <string>
#include <vector>
using namespace std;
class Pitcher
{
private:
string _name;
double _ERA1;
double _ERA2;
public:
Pitcher();
Pitcher(string, double, double);
vector<Pitcher> Pitchers;
string GetName();
double GetERA1();
double GetERA2();
void InsertionSort(vector<Pitcher>&);
~Pitcher();
};
#endif
#include "Pitcher.h"
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;
Pitcher::Pitcher()
{
}
Pitcher::~Pitcher()
{
}
string Pitcher::GetName()
{
return _name;
}
Pitcher::Pitcher(string name, double ERA1, double ERA2)
{
_name = name;
_ERA1 = ERA1;
_ERA2 = ERA2;
}
double Pitcher::GetERA1()
{
return _ERA1;
}
double Pitcher::GetERA2()
{
return _ERA2;
}
#include "Pitcher.h"
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
void InsertionSort(vector<Pitcher> Pitchers&);
using namespace std;
int main()
{
vector<Pitcher> Pitchers;
cout << "Pitcher" << setw(19) << "Item ERA1" << setw(13) <<
"Item ERA2\n" << endl;
Pitcher h2("Bob Jones", 1.32, 3.49);
Pitchers.push_back(h2);
Pitcher h3("F Mason", 7.34, 2.07);
Pitchers.push_back(h3);
Pitcher h1("RA Dice", 0.98, 6.44);
Pitchers.push_back(h1);
for(unsigned i = 0; i < Pitchers.size(); ++i)
{
cout << setw(19);
cout << left << Pitchers[i].GetName() << "$" <<
setw(10) << Pitchers[i].GetERA1() <<
right << "$" << Pitchers[i].GetERA2() << "\n";
}
cout << endl;
//------------------------------------------------------
InsertionSort(Pitchers);
//Now print the numbers
cout<<"The numbers in the vector after the sort are:"<<endl;
for(int i = 0; i < Pitchers.size(); i++)
{
cout<<Pitchers[i].GetERA1()<<" ";
}
cout<<endl<<endl;
system("PAUSE");
return 0;
}
void InsertionSort(vector<Pitcher> &Pitchers)
{
int firstOutOfOrder = 0;
int location = 0;
int temp;
int totalComparisons = 0; //debug purposes
for(firstOutOfOrder = 1; firstOutOfOrder < Pitchers.size() ; firstOutOfOrder++)
{
if(Pitcher.GetERA1([firstOutOfOrder]) < Pitcher.GetERA1[firstOutOfOrder - 1])
{
temp = Pitcher[firstOutOfOrder];
location = firstOutOfOrder;
do
{
totalComparisons++;
Pitcher.GetERA1[location] = Pitcher.GetERA1[location - 1];
location--;
}while(location > 0 && Pitcher.GetERA1[location - 1] > temp);
Pitcher.GetERA1[location] = temp;
}
}
cout<<endl<<endl<<"Comparisons: "<<totalComparisons<<endl<<endl;
}
Here:
for(firstOutOfOrder = 1; firstOutOfOrder < Pitchers.size() ; firstOutOfOrder++)
{
if(Pitchers[firstOutOfOrder].GetERA1() < Pitchers[firstOutOfOrder-1].GetERA1())
{ //^^^your way was not right, should first access the object then
//access member function
temp = Pitcher[firstOutOfOrder];
//^^^should be Pitchers, similar errors below
location = firstOutOfOrder;
do
{
totalComparisons++;
Pitcher.GetERA1[location] = Pitcher.GetERA1[location - 1];
//^^^similar error as inside if condition
location--;
}while(location > 0 && Pitcher.GetERA1[location - 1] > temp);
//^^^similar error as inside if condition
Pitcher.GetERA1[location] = temp;
//^^similar error as in if condition and name error
}
}
Meanwhile, you put the InsertionSort declaration as a member of the Pitcher class
public:
.
.
void InsertionSort(vector<Pitcher>&);
and you also declare the same function inside main,
void InsertionSort(vector<Pitcher> Pitchers&);
//should be vector<Pitcher>& Pitchers
using namespace std;
int main()
the member function probably should be removed in your case. InsertionSort is not a responsibility of your Pitcher class.
Unless this is homework, you're better off using the build in sort from
<algorithm>