Skip to content

Commit

Permalink
Added loadFromString() method to Graph class.
Browse files Browse the repository at this point in the history
todo: make it robust to errors in the input string.

Signed-off-by: unknown <saq10002@iteb-219.ad.engr.uconn.edu>
  • Loading branch information
unknown committed Sep 22, 2014
1 parent 34f5001 commit b902e11
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 11 deletions.
155 changes: 145 additions & 10 deletions YASI_12/ds.graph.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#pragma once
#include "common.h"
#include <sstream>
#include <string>
#include "ds.doublylinkedlist.h"
#include "ds.IntLinearProbingHashTable.h"
using namespace std;

namespace yasi{
Expand All @@ -13,37 +16,169 @@ class EdgeBase;
template<class V, class Element>
struct Edge{
Element element;
V *pStart, *pEnd;
float weight;
V *start, *end;
Edge(V* v1 = NULL, V* v2 = NULL, float w = 0) : start(v1), end(v2), weight(w){}
};

template<class E>
typedef DoublyLinkedList< E > EdgeList;

template<class Element, class EdgeElement>
struct Vertex{
protected:
typedef Vertex<Element, EdgeElement> self;
typedef Edge<self, EdgeElement> edge;
public:
typedef DoublyLinkedList< edge > EdgeList;
typedef DoublyLinkedList< edge* > EdgeList;
int id;
Element element;
EdgeList* pInEdges;
EdgeList* pOutEdges;

Vertex(int id = 0) :id(id){
pInEdges = new EdgeList;
pOutEdges = new EdgeList;
}

virtual ~Vertex(){
DELETE_SAFE(pInEdges);
DELETE_SAFE(pOutEdges);
}
};

class IGraph{
public:
virtual ~IGraph(){}
virtual int numVertices() const = 0;
virtual int numEdges() const = 0;
};

/// Adjacency list data structure
template<class VertexElement, class EdgeElement>
class Graph{
// directed weighted graph
template<class VertexElement = int, class EdgeElement = char>
class Graph : public IGraph{
/////////////// enable testing /////////////
friend class GraphTest;
public:
typedef Vertex<VertexElement, EdgeElement> VertexType;
typedef Edge<VertexType, EdgeElement> EdgeType;
typedef DoublyLinkedList<VertexType*> VertexList;
typedef DoublyLinkedList<EdgeType*> EdgeList;
protected:
VertexList* vertexList;
EdgeList* edgeList;
VertexList vertexList;
EdgeList edgeList;
const bool _weighted;

void clear(){
for (VertexList::iterator i = vertexList.begin(); i != vertexList.end(); i++){
DELETE_SAFE(*i);
}
vertexList.clear();
for (EdgeList::iterator i = edgeList.begin(); i != edgeList.end(); i++){
DELETE_SAFE(*i);
}
edgeList.clear();
}
public:
Graph(bool weighted = true) :_weighted(weighted){
}
virtual ~Graph(){
}
int numVertices() const override{
return vertexList.size();
}
int numEdges() const override{
return edgeList.size();
}
EdgeType* addEdge(VertexType* v1, VertexType* v2, float w = 0){
EdgeType* edge = new EdgeType(v1, v2, w);
edgeList.pushBack(edge);
v1->pOutEdges->pushBack(edge);
v2->pInEdges->pushBack(edge);
return edge;
}
VertexType* addVertex(int id){
VertexType* pVertex = new VertexType(id);
vertexList.pushBack(pVertex);
return pVertex;
}
VertexType* addVertex(int id, VertexElement e){
VertexType* pVertex = addVertex(id);
pVertex->element = e;
return pVertex;
}

// strEdgeList contains non-empty lines
// one line for each edge
// line format: vid1 vid2 weight
void loadFromString(string strEdgeList){
clear();
stringstream inp(trim(strEdgeList));

// use a temporary hashtable
IntLinearProbingHashTable< VertexType* > ht;

while (! inp.eof()){
int vid1, vid2;
float w;
// vertices
inp >> vid1 >> vid2;
// edge weight
if (_weighted){
inp >> w;
}
else{
w = 0;
}

// create vertices
// add them to the graph if not already there
VertexType **ppv1, **ppv2;
VertexType *pv1, *pv2;

// first vertex
ppv1 = ht.get(vid1);
if (!ppv1){
pv1 = addVertex(vid1);
ht.put(vid1, pv1);
}
else{
pv1 = *ppv1;
}
// second vertex
ppv2 = ht.get(vid2);
if (!ppv2){
pv2 = addVertex(vid2);
ht.put(vid2, pv2);
}
else{
pv2 = *ppv2;
}
// create edge
addEdge(pv1, pv2, w);
}
}
}; // class Graph

class GraphTest : public yasi::Test{
public:
void loadFromString(){
Graph<int> g;

// simple triangle
string triangle =
"1 2 12\n"
"1 3 13\n"
"2 3 23\n";
g.loadFromString(triangle);

// test
ASSERT_EQ(3, g.numVertices());
ASSERT_EQ(3, g.numEdges());
}

};

}
}
ADD_TEST_F(GraphTest, loadFromString);

} // namespace ds
} // namespace yasi
1 change: 1 addition & 0 deletions YASI_12/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "ds.intlinearprobinghashtable.h"
#include "ds.linearprobinghashtable.h"
#include "ds.hopscotchhashtable.h"
#include "ds.graph.h"

//#include "Sorter.h"

Expand Down
27 changes: 27 additions & 0 deletions YASI_12/utils.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#pragma once
#include "common.h"
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <string>
using namespace std;

Expand Down Expand Up @@ -83,6 +87,29 @@ int whichPowerOfTwo(unsigned int n){
}
}


//////////////////////////////////////////
//// string trimming functions from
//// http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring
/////////////////////////////////////////

// trim from start
inline std::string &ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}

// trim from end
inline std::string &rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}

// trim from both ends
inline std::string &trim(std::string &s) {
return ltrim(rtrim(s));
}

///////////// enable in compile-time a certain code block depending on boolean predicate /////////////
///////////// also, check if a certain class contains a certain function ///////////////////////////////
//////////////////////// see http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence#264088
Expand Down
Binary file modified gtest-1.7.0/msvc/gtest/gtest.tlog/CL.read.1.tlog
Binary file not shown.
Binary file modified gtest-1.7.0/msvc/gtest/gtest.tlog/CL.write.1.tlog
Binary file not shown.
Binary file modified gtest-1.7.0/msvc/gtest/gtest.tlog/Lib-link.read.1.tlog
Binary file not shown.
Binary file modified gtest-1.7.0/msvc/gtest/gtest.tlog/Lib-link.write.1.tlog
Binary file not shown.
Binary file modified gtest-1.7.0/msvc/gtest/gtest.tlog/cl.command.1.tlog
Binary file not shown.
2 changes: 1 addition & 1 deletion gtest-1.7.0/msvc/gtest/gtest.tlog/gtest.lastbuildstate
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit
Debug|Win32|D:\DropBox\My Dropbox\Projects\C++\YASI\|
Debug|Win32|C:\Saad\Dropbox\Projects\C++\YASI\|
Binary file modified gtest-1.7.0/msvc/gtest/gtest.tlog/lib.command.1.tlog
Binary file not shown.
Binary file modified gtest-1.7.0/msvc/gtest/vc120.idb
Binary file not shown.
Binary file modified gtest-1.7.0/msvc/gtestd.lib
Binary file not shown.

0 comments on commit b902e11

Please sign in to comment.