HW4: formatted

This commit is contained in:
Claudio Maggioni 2019-12-19 13:51:48 +01:00
parent 5827c13df2
commit ecfdcbf96b
1 changed files with 159 additions and 131 deletions

View File

@ -1,4 +1,15 @@
// vim: set ts=4 sw=4 et tw=80:
// vim: set ts=3 sw=3 et tw=80:
/* Assignment 4 - Chess paths
* Claudio Maggioni
*
* External sources used:
* - cppreference.com
* - DFS wikipedia implementation (adapted).
*
* The flag DEBUG, if defined, activates some debug messages printe on stdout.
* This is disabled to comply with tests.
*/
#include "roadmap.h"
#include <iostream>
@ -8,146 +19,163 @@
#include <stack>
using namespace std;
#define DEBUG 1
class ConcreteRoadMap : public AbstractRoadMap {
private:
map< string, set<string> > adj;
private:
map< string, set<string> > adj;
/*
* Adds in the map for key city1 a new set with city2 inside if there is
* no prior set, otherwise it appends city2 into the existing set
*/
void addPair(const string& city1, const string& city2) {
this->adj[city1].insert(city2);
}
/*
* Adds in the map for key city1 a new set with city2 inside if there is
* no prior set, otherwise it appends city2 into the existing set
*/
void addPair(const string& city1, const string& city2) {
this->adj[city1].insert(city2);
}
public:
ConcreteRoadMap() : adj() {};
public:
ConcreteRoadMap() : adj() {};
void addRoad(const string& city1, const string& city2) override {
addPair(city1, city2);
addPair(city2, city1);
}
void addRoad(const string& city1, const string& city2) override;
void addRoad(const vector<string>& cities) override {
for (size_t i = 0; i < cities.size() - 1; i++) {
addRoad(cities[i], cities[i + 1]);
}
}
void addRoad(const vector<string>& cities) override;
void clear() override {
this->adj.clear();
}
void clear() override;
int neighborCountForCity(const string& city) const override {
auto i = this->adj.find(city);
if (i == adj.end()) return -1;
return i->second.size();
}
int neighborCountForCity(const string& city) const override;
bool hasLoop() const override {
stack< std::pair<string, string> > s;
set<string> discovered;
bool search_comp;
bool hasLoop() const override;
for (auto itr = adj.begin(); itr != adj.end(); ++itr) {
search_comp = true;
s.push(std::pair<string, string>(itr->first, itr->first));
while (!s.empty()) {
const std::pair<string, string> v = s.top();
#if DEBUG
std::cout << "Front is: " << v.first << " with parent " <<
v.second << "\n";
#endif
s.pop();
if (discovered.find(v.first) == discovered.end()) {
search_comp = false;
discovered.insert(v.first);
const auto i = this->adj.find(v.first);
const auto set = i->second;
for (auto j = set.begin(); j != set.end(); ++j) {
if (*j != v.second) {
#if DEBUG
cout << "Neighbor: " << *j << " parent: " <<
v.first << "\n";
#endif
s.push(std::pair<string, string>(*j,
v.first));
}
}
} else if (!search_comp) {
// cout << v.first << " is discovered\n";
return true;
}
}
}
return false;
}
bool reachable(const string& c1, const string& c2) const override;
bool reachable(const string& c1, const string& c2) const override {
if (adj.find(c1) == adj.end() ||
adj.find(c2) == adj.end()) {
return false;
}
deque<string> s;
set<string> discovered;
s.push_back(c1);
while (!s.empty()) {
const string& v = s.front();
if (v == c2) return true;
s.pop_front();
discovered.insert(v);
const auto i = this->adj.find(v);
const auto set = i->second;
for (auto j = set.begin(); j != set.end(); ++j) {
if (discovered.find(*j) == discovered.end()) {
s.push_back(*j);
}
}
}
return false;
}
int countIslands() const override {
int islands = 0;
bool first;
stack< std::pair<string, string> > s;
set<string> discovered;
for (auto itr = adj.begin(); itr != adj.end(); ++itr) {
s.push(std::pair<string, string>(itr->first, itr->first));
first = true;
while (!s.empty()) {
const std::pair<string, string>& v = s.top();
s.pop();
if (discovered.find(v.first) == discovered.end()) {
if (first) {
islands++;
}
discovered.insert(v.first);
const auto i = this->adj.find(v.first);
const auto set = i->second;
for (auto j = set.begin(); j != set.end(); ++j) {
if (*j != v.second) {
s.push(std::pair<string, string>(*j, v.first));
}
}
}
first = false;
}
}
return islands;
}
int countIslands() const override;
};
AbstractRoadMap* createRoadMap() {
return new ConcreteRoadMap();
void ConcreteRoadMap::addRoad(const string& city1, const string& city2) {
addPair(city1, city2);
addPair(city2, city1);
}
void ConcreteRoadMap::addRoad(const vector<string>& cities) {
for (size_t i = 0; i < cities.size() - 1; i++) {
addRoad(cities[i], cities[i + 1]);
}
}
void ConcreteRoadMap::clear() {
adj.clear();
}
int ConcreteRoadMap::neighborCountForCity(const string& city) const {
auto i = this->adj.find(city);
if (i == adj.end()) return -1;
return i->second.size();
}
bool ConcreteRoadMap::hasLoop() const {
stack< std::pair<string, string> > s;
set<string> discovered;
bool search_comp;
for (auto itr = adj.begin(); itr != adj.end(); ++itr) {
search_comp = true;
s.push(std::pair<string, string>(itr->first, itr->first));
while (!s.empty()) {
const std::pair<string, string> v = s.top();
#if DEBUG
std::cout << "Front is: " << v.first << " with parent " <<
v.second << "\n";
#endif
s.pop();
if (discovered.find(v.first) == discovered.end()) {
search_comp = false;
discovered.insert(v.first);
const auto i = this->adj.find(v.first);
const auto set = i->second;
for (auto j = set.begin(); j != set.end(); ++j) {
if (*j != v.second) {
#if DEBUG
cout << "Neighbor: " << *j << " parent: " <<
v.first << "\n";
#endif
s.push(std::pair<string, string>(*j,
v.first));
}
}
} else if (!search_comp) {
#if DEBUG
cout << v.first << " is discovered\n";
#endif
return true;
}
}
}
return false;
}
bool ConcreteRoadMap::reachable(const string& c1, const string& c2) const {
if (adj.find(c1) == adj.end() ||
adj.find(c2) == adj.end()) {
return false;
}
deque<string> s;
set<string> discovered;
s.push_back(c1);
while (!s.empty()) {
const string& v = s.front();
if (v == c2) return true;
s.pop_front();
discovered.insert(v);
const auto i = this->adj.find(v);
const auto set = i->second;
for (auto j = set.begin(); j != set.end(); ++j) {
if (discovered.find(*j) == discovered.end()) {
s.push_back(*j);
}
}
}
return false;
}
int ConcreteRoadMap::countIslands() const {
int islands = 0;
bool first;
stack< std::pair<string, string> > s;
set<string> discovered;
for (auto itr = adj.begin(); itr != adj.end(); ++itr) {
s.push(std::pair<string, string>(itr->first, itr->first));
first = true;
while (!s.empty()) {
const std::pair<string, string>& v = s.top();
s.pop();
if (discovered.find(v.first) == discovered.end()) {
if (first) {
islands++;
}
discovered.insert(v.first);
const auto i = this->adj.find(v.first);
const auto set = i->second;
for (auto j = set.begin(); j != set.end(); ++j) {
if (*j != v.second) {
s.push(std::pair<string, string>(*j, v.first));
}
}
}
first = false;
}
}
return islands;
}
AbstractRoadMap* createRoadMap() {
return new ConcreteRoadMap();
}