Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions group/assignment5/Graph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#include "Graph.h"

/*returns a pointer of the son having data equal to the given node's data in
the graph,
otherwise returns null*/
Node* Graph::Node::findSon(Node* node) {
if (node == nullptr) {
return nullptr;
}

for (Node* son : sons) {
if (son == nullptr) {
continue;
}
if (son->data == node->data) {
return son;
}
}
return nullptr;
}

Graph::Node::Node(char data) : data(data), sons(vector<Node*>()), inRank(0) {}

/*Adds node as a son of this node if it's not already a son of it.
returns true if the son is succefully added, and false otherwise*/
bool Graph::Node::addSon(Node* node) {
if (node == nullptr) {
return false;
}
Node* actualSon = findSon(node);
if (actualSon == nullptr) {
node->inRank++;
sons.push_back(node);
return true;
}
return false;
}

/******************************************************************************/

/*helping method that inserts the vertices's data to the alphabet vetctor,
in a topoligical order*/
void Graph::topologicalSortAux(vector<Node*> nodes, vector<char>& alphabet) {
if (nodes.size() == 0) {
return;
}
for (vector<Node*>::iterator i = nodes.begin(); i != nodes.end(); i++) {
if (*i == nullptr) {
continue;
}
if ((*i)->inRank == 0) {
alphabet.push_back((*i)->data);
for (Node* son : (*i)->sons) {
if (son != nullptr) {
son->inRank--;
}
}
nodes.erase(i);
topologicalSortAux(nodes, alphabet);
break;
}
}
}

/*helping function to the Graph desrtructor,
it deletes the vertices in a topoligical order*/
void Graph::topologicalOrderDelete(vector<Node*> nodes) {
if (nodes.size() == 0) {
return;
}
for (vector<Node*>::iterator i = nodes.begin(); i != nodes.end(); i++) {
if (*i == nullptr) {
continue;
}
if ((*i)->inRank == 0) {
for (Node* son : (*i)->sons) {
if (son != nullptr) {
son->inRank--;
}
}
delete (*i);
nodes.erase(i);
topologicalOrderDelete(nodes);
break;
}
}
}

Graph::Graph() : vertices(vector<Node*>()) {}

Graph::~Graph() { topologicalOrderDelete(vertices); }
/*searches for a vertix with the given char data and returns a pointer to it,
returns nullptr in any case of error and in case it's not found in the graph*/
Node* findVertix(char c) {
for (Node* node : vertices) {
if (node == nullptr) {
continue;
}
if (node->data == c) {
return node;
}
}
return nullptr;
}

/*adds edge from the vertox with char data a to vertox with char data b,
return true if adding the edge has been succefully done,and false otherwise*/
bool Graph::addEdge(char a, char b) {
Node* from = findVertix(a);
if (from == nullptr) {
from = new Node(a);
vertices.push_back(from);
}
Node* to = findVertix(b);
if (to == nullptr) {
to = new Node(b);
vertices.push_back(to);
}
from->addSon(to);
}

/*returns a vector of the data in the graph in a topological order */
vector<char> Graph::topologicalSort() {
vector<char> alphabet = vector<char>();
topologicalSortAux(vertices, alphabet);
return alphabet;
}
55 changes: 55 additions & 0 deletions group/assignment5/Graph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <iostream>
#include <vector>
#include <string>

using namespace std;

/*The Graph class: to be built according to a dictionary*/
class Graph {
/******************************************************************************/
class Node {
char data;
vector<Node*> sons;
/*counts the number of edges entring to this node*/
int inRank;
friend class Graph;

/*returns a pointer of the son having data equal to the given node's data in
the graph,
otherwise returns null*/
Node* findSon(Node* node);

public:
Node(char data);

/*Adds node as a son of this node if it's not already a son of it.
returns true if the son is succefully added, and false otherwise*/
bool addSon(Node* node);
};
/******************************************************************************/

/*the vertices in te graph contains*/
vector<Node*> vertices;

/*helping method that inserts the vertices's data to the alphabet vetctor,
in a topoligical order*/
void topologicalSortAux(vector<Node*> nodes, vector<char>& alphabet);

/*helping function to the Graph desrtructor,
it deletes the vertices in a topoligical order*/
void topologicalOrderDelete(vector<Node*> nodes);

public:
Graph() : vertices(vector<Node*>()) {}

~Graph() { topologicalOrderDelete(vertices); }
/*searches for a vertix with the given char data and returns a pointer to it,
returns nullptr in any case of error and in case it's not found in the graph*/
Node* findVertix(char c);
/*adds edge from the vertox with char data a to vertox with char data b,
return true if adding the edge has been succefully done,and false otherwise*/
bool addEdge(char a, char b);

/*returns a vector of the data in the graph in a topological order */
vector<char> topologicalSort();
};
57 changes: 57 additions & 0 deletions group/assignment5/Testing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <iostream>
#include <vector>
#include "UnknownAlphabet.h"
using namespace std;

/****************************Testing*******************************************/

#define EXPECT_EQ(expected, actual) \
if ((expected) != (actual)) { \
std::cout << __FILE__ << ":" << __LINE__ << " Failed: " << std::endl; \
}

void GenaralDictionaryTest1() {
UnknownAlphabet a({"ART", "RAT", "CAT", "CAR"});
vector<char> expected = {'A', 'T', 'R', 'C'};
EXPECT_EQ(expected, a.findAlphabet());
}

void GenaralDictionaryTest2() {
UnknownAlphabet a({"abc", "$$"});
vector<char> expected = {'a', '$', 'b', 'c'};
EXPECT_EQ(expected, a.findAlphabet());
}

void oneWordDictionaryTest() {
UnknownAlphabet a({"xyzr"});
vector<char> expected = {'x', 'y', 'z', 'r'};
EXPECT_EQ(expected, a.findAlphabet());
}

void emptyDictionaryTest() {
UnknownAlphabet a({""});
vector<char> expected = {};
EXPECT_EQ(expected, a.findAlphabet());
}

void GenaralDictionaryTest3() {
UnknownAlphabet a({"xa", "xaby", "xac", "c", "a"});
vector<char> expected = {'b', 'x', 'c', 'a', 'y'};
EXPECT_EQ(expected, a.findAlphabet());
}

void oneLetterDictionary() {
UnknownAlphabet a({"aaaa", "a", "aa"});
vector<char> expected = {'a'};
EXPECT_EQ(expected, a.findAlphabet());
}

int main() {
GenaralDictionaryTest1();
GenaralDictionaryTest2();
oneWordDictionaryTest();
emptyDictionaryTest();
oneLetterDictionary();
GenaralDictionaryTest3();
return 0;
}
57 changes: 57 additions & 0 deletions group/assignment5/UnknownAlphabet.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "UnknownAlphabet.h"

/*helping method the compares two strings and returns a pair of chars,
the pair is the first different char between the two strings if foud,
otherwise returns a piar of empty chars to indicate that there are no
differnces.*/
pair<char, char> UnknownAlphabet::findFirstDifference(string s1, string s2) {
int size = min(s1.size(), s2.size());
pair<char, char> p(' ', ' ');
for (int i = 0; i < size; i++) {
if (s1[i] != s2[i]) {
p.first = s1[i];
p.second = s2[i];
return p;
}
}
return p;
}

/*extracts all the letters used in the dictionary to the letters vector.*/
void UnknownAlphabet::getLetters(string s) {
for (char c : s) {
letters.push_back(c);
}
}
/*checks if the given char is a member of the given vector,
and returns a boolean value accordingly*/
bool UnknownAlphabet::charExists(vector<char> v, char c) {
for (char ch : v) {
if (ch == c) {
return true;
}
}
return false;
}

UnknownAlphabet::UnknownAlphabet(vector<string> dictionary)
: dictGraph(Graph()) {
for (int i = 0; i < dictionary.size() - 1; i++) {
pair<char, char> p = findFirstDifference(dictionary[i], dictionary[i + 1]);
dictGraph.addEdge(p.first, p.second);
}
for (string word : dictionary) {
getLetters(word);
}
}

/*returns a vector of the dictionary alphabet*/
vector<char> UnknownAlphabet::findAlphabet() {
vector<char> alphabet = dictGraph.topologicalSort();
for (char c : letters) {
if (!charExists(alphabet, c)) {
alphabet.push_back(c);
}
}
return alphabet;
}
33 changes: 33 additions & 0 deletions group/assignment5/UnknownAlphabet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <iostream>
#include <vector>
#include <string>
#include "Graph.h"

using namespace std;

/*UnknownAlphabet:
class members: a graph to be built in the constructor according to a given
dictionary:
letters of the dictionary are vertices in the graph,
an edge (u,v) is added to the graph if u is lexicographicaly smaller than v*/
class UnknownAlphabet {
Graph dictGraph;
/*all the letters used in the dictionary*/
vector<char> letters;
/*helping method the compares two strings and returns a pair of chars,
the pair is the first different char between the two strings if foud,
otherwise returns a piar of empty chars to indicate that there are no
differnces.*/
pair<char, char> findFirstDifference(string s1, string s2);
/*extracts all the letters used in the dictionary to the letters vector.*/
void getLetters(string s);
/*checks if the given char is a member of the given vector,
and returns a boolean value accordingly*/
bool charExists(vector<char> v, char c);

public:
UnknownAlphabet(vector<string> dictionary);

/*returns a vector of the dictionary alphabet*/
vector<char> findAlphabet();
};