HW4: formatted
This commit is contained in:
parent
5827c13df2
commit
ecfdcbf96b
1 changed files with 159 additions and 131 deletions
|
@ -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 "roadmap.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -8,146 +19,163 @@
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
#define DEBUG 1
|
||||||
class ConcreteRoadMap : public AbstractRoadMap {
|
class ConcreteRoadMap : public AbstractRoadMap {
|
||||||
private:
|
private:
|
||||||
map< string, set<string> > adj;
|
map< string, set<string> > adj;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds in the map for key city1 a new set with city2 inside if there is
|
* 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
|
* no prior set, otherwise it appends city2 into the existing set
|
||||||
*/
|
*/
|
||||||
void addPair(const string& city1, const string& city2) {
|
void addPair(const string& city1, const string& city2) {
|
||||||
this->adj[city1].insert(city2);
|
this->adj[city1].insert(city2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConcreteRoadMap() : adj() {};
|
ConcreteRoadMap() : adj() {};
|
||||||
|
|
||||||
void addRoad(const string& city1, const string& city2) override {
|
void addRoad(const string& city1, const string& city2) override;
|
||||||
addPair(city1, city2);
|
|
||||||
addPair(city2, city1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addRoad(const vector<string>& cities) 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 clear() override {
|
void clear() override;
|
||||||
this->adj.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int neighborCountForCity(const string& city) const override {
|
int neighborCountForCity(const string& city) const override;
|
||||||
auto i = this->adj.find(city);
|
|
||||||
if (i == adj.end()) return -1;
|
|
||||||
return i->second.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasLoop() const override {
|
bool hasLoop() const override;
|
||||||
stack< std::pair<string, string> > s;
|
|
||||||
set<string> discovered;
|
|
||||||
bool search_comp;
|
|
||||||
|
|
||||||
for (auto itr = adj.begin(); itr != adj.end(); ++itr) {
|
bool reachable(const string& c1, const string& c2) const override;
|
||||||
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 {
|
int countIslands() 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;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue