-2

I have to implement a simulation of the WWW on c++ using graphs, where the nodes are Webpages and the directed edges are URLs.

In school, in our level, we are still starting in Object Oriented Programming, so they proposed to implement using the adjacency lists and adjacency matrices, but I don't like them, for they are memory monsters and very limited.

Question:
Can you propose another Data Structure (preferably Object Oriented stuff) that uses pointers (as edges) to other nodes, and where I can dynamically generate as many edges as I like???

I have read this but I haven't find anything helpful : Object Oriented implementation of graph data structures

Community
  • 1
  • 1
Salim Mahboubi
  • 561
  • 7
  • 25
  • What about the other related links appearing in the **Related** section at the right side of your question? – πάντα ῥεῖ Apr 15 '14 at 20:41
  • Nope, most of the use Adjacence lists or are about errors, nothing about a structure like the one i stated. – Salim Mahboubi Apr 15 '14 at 20:52
  • _'like the one i stated'_ Then it might be about time, to add some clarifying code sample of what you have been trying already, to your question (please don't post any code as comment!). – πάντα ῥεῖ Apr 15 '14 at 20:55
  • I have edited my answer a few times to fix/flesh out the code sample I include. Please accept the answer or elaborate on your question because it's a little unclear how to answer this. – M2tM Apr 15 '14 at 21:26

1 Answers1

2

Honestly trying to represent this in just one data structure will end up being pretty inefficient. In reality you have a smaller list of domain registrars which provide the lookup. Something more accurate than a single dumb graph would be:

#include <iostream>
#include <memory>
#include <map>
#include <vector>
#include <string>
#include <set>

class Webpage;
class Registrar : public std::enable_shared_from_this<Registrar> {
public:
    std::shared_ptr<Webpage> resolve(const std::string &url);
private:
    std::map<std::string, std::shared_ptr<Webpage>> pages;
};

class Webpage {
public:
    Webpage(std::shared_ptr<Registrar> registrar, const std::string &url) :
        registrar(registrar),
        url(url){
    }

    std::shared_ptr<Webpage> addLink(const std::string &url){
        links.push_back(url);
        return registrar->resolve(url);
    }

    std::vector<std::shared_ptr<Webpage>> resolvePageLinks(){
        std::vector<std::shared_ptr<Webpage>> pages;
        for (auto &linkUrl : links){
            pages.push_back(registrar->resolve(linkUrl));
        }
        return pages;
    }

    std::string getUrl() const{
        return url;
    }
private:
    std::string url;
    std::shared_ptr<Registrar> registrar;
    std::vector<std::string> links;
};

std::shared_ptr<Webpage> Registrar::resolve(const std::string &url){
    auto found = pages.find(url);
    if (found != pages.end()){
        return found->second;
    }
    else{
        auto webpage = std::make_shared<Webpage>(shared_from_this(), url);
        pages.insert({url, webpage});
        return webpage;
    }
}

void printPageHierarchy(std::shared_ptr<Webpage> current, int depth, std::set<std::shared_ptr<Webpage>> &visited){
    std::cout << std::string(3*depth, ' ');
    std::cout << current->getUrl() << std::endl;
    if (visited.find(current) == visited.end()){
        visited.insert(current);
        ++depth;
        for (auto page : current->resolvePageLinks()){
            printPageHierarchy(page, depth, visited);
        }
    }else{
        std::cout << std::string(3*depth, ' ');
        std::cout << "..." << std::endl;
    }
}

void printPageHierarchy(std::shared_ptr<Webpage> current){
    std::set<std::shared_ptr<Webpage>> visited;
    printPageHierarchy(current, 0, visited);
}

int main(){
    auto registrar = std::make_shared<Registrar>();
    auto site1 = registrar->resolve("site1.com");
    site1->addLink("site2.com");
    site1->addLink("site3.com")->addLink("site4.com")->addLink("site1.com");
    std::cout << "From site1.com:" << std::endl;    
    printPageHierarchy(site1);

    std::cout << "_____________\nFrom site3.com:" << std::endl;
    printPageHierarchy(registrar->resolve("site3.com"));
}

This is pretty simplistic, and obviously minimal. Your question makes it a little unclear what exactly your requirements actually are.

M2tM
  • 4,415
  • 1
  • 34
  • 43
  • I think that this is the answer I want, but Codeblocks using GNU GCC doesn't compile this – Salim Mahboubi Apr 15 '14 at 21:34
  • It relies on C++11. I can compile it in visual studio, clang should compile it as well, and GCC 4.5+ should as well. – M2tM Apr 15 '14 at 21:38
  • Ah ! Thanks, I hope That you don't mind that I keep the thread open till I fully understand and successfully compile this, or another proposition. Thanks. – Salim Mahboubi Apr 15 '14 at 21:41
  • Please, just update again when you figure it out. :) I double-checked and the solution (as it is right now on the page) does indeed compile in MSVS 2013, and I do not use anything non-standard so it should also work as long as C++11 is enabled (you may have an old compiler, or you may be missing a C++11 compile flag). Feel free to ask if you have further questions. My skype is Dervacor. – M2tM Apr 15 '14 at 21:42
  • Added a second call to printPageHeirarchy to show printing it from site3.com's perspective as well. – M2tM Apr 15 '14 at 21:53
  • 1
    I finally managed to compile c++11, now I'll read some courses about it to understand your code especially those lots of brackets. :p Thank you very much. – Salim Mahboubi Apr 15 '14 at 22:23
  • I'd recommend The C++ Programming Language by Bjarne Stroustrup. http://www.stroustrup.com/4th.html – M2tM Apr 15 '14 at 22:33
  • Don't make other people's homework for them until they put in some effort themselves next time ... – Marc Claesen Apr 16 '14 at 08:36
  • @MarcClaesen I doubt he'd be able to directly copy/paste my answer into an assignment without being accused of plagiarism, especially if his other work doesn't look like this. In understanding my answer enough to actually apply the concepts to his own implementation, or so that he can even just explain it, he will have learned more than the original task would have taught him anyway. Homework for the sake of it is meaningless, learning is important. – M2tM Apr 16 '14 at 18:15
  • Thanks for accepting. How did your homework go? – M2tM May 02 '14 at 18:09