2021-1 用符号作为顶点名的图的API c++实现

输入格式

在这里插入图片描述
不需要知道边数,也没有直接给出顶点数。但是,通过两次扫描文件routes.txt,建立

  • 符号表 Sting -> id 从【机场名】找到标志符【ID】
  • 反向索引,从【ID】 找到【机场名】,即数组keys[]
  • 存储【ID】的无向图

在这里插入图片描述

API

在这里插入图片描述

SymbolGraph.h

头文件见 Graph.h Paths.h


#pragma once
#include<map>
#include<sstream> 
#include"Graph.h"
#include"Paths.h"

/****************如无必要,勿增实体********************/
class SymbolGraph
{
public:
	SymbolGraph() {}
	SymbolGraph(string file, char sp);


	bool contains(string key) {
		return m_keyToID->find(key) != m_keyToID->end();
	}

	int index(string key) {
		return m_keyToID->at(key);
	}

	string name(int idx) {
		return m_keys->at(idx);
	}

	Graph* G() {
		return m_graph;
	}
private:
	map<string, int>* m_keyToID = nullptr;//键值-> ID
	vector<string>* m_keys = nullptr;//ID -> 键值
	Graph* m_graph = nullptr;

	vector<string>* split(string s, char sep);
};

void degreeOfSeparation(string file, string goalStr);
void testSymbolGraph();


SymbolGraph.cpp

 #include "SymbolGraph.h"

#define out(x) cout<<x<<" "
#define hh printf_s("\n")//换行

/*
* 要求文件里面的边只出现一次,即无向图,添加边时自动完成from->to to->from
* 格式:起点 邻接点1 邻接点2 邻接点3 ~
*/
SymbolGraph::SymbolGraph(string file, char sp)
{
    m_keyToID = new map<string, int>();

    ifstream stream(file, ios::in);
    string lineStr = "";
    while (getline(stream, lineStr)) {
        vector<string>* tmp = split(lineStr, sp);

        int n = tmp->size();
        for (int i = 0; i < n; i++)
        {
            if (m_keyToID->find(tmp->at(i)) == m_keyToID->end()) {
                m_keyToID->emplace(tmp->at(i), m_keyToID->size());
            }
        }
    }

    //构造键值表
    int v = m_keyToID->size();
    m_keys = new vector<string>(v);
    for (auto it = m_keyToID->begin(); it != m_keyToID->end(); ++it) {
        m_keys->at(it->second) = it->first;
    }

    //初始化顶点
    m_graph = new Graph(v);

    //添加边
    ifstream in(file, ios::in);
    while (getline(in, lineStr)) {
        vector<string>* tmp = split(lineStr, sp);
        int n = tmp->size();
        int v = m_keyToID->at(tmp->at(0));
        for (int i = 1; i < n; i++)
        {
            int w = m_keyToID->at(tmp->at(i));
            m_graph->addEdge(v, w);//添加无向边
        }
    }


}

vector<string>* SymbolGraph::split(string s, char sep)
{
    istringstream iss(s);
    vector<string>* res = new vector<string>();
    string buffer;
    while (getline(iss, buffer, sep)) {
        res->push_back(buffer);
    }
    return res;
}

void degreeOfSeparation(string file, string startName,char sp)
{
    SymbolGraph* sg = new SymbolGraph(file, sp);
    Graph* graph = sg->G();

    if (!sg->contains(startName)) {
        out(startName), out(" not in dataBase."), hh;
        return;
    }

    int s = sg->index(startName);
    Paths path(*graph, s);//默认是广度优先搜索
   

    out("input search name, input q to quit.\n");
    string next = "";
    while (true) {
        getline(cin,next);
        if (next == "q") break;
        if (sg->contains(next)) {
            int t = sg->index(next);
            if (path.hasPathto(t)) {
                for (auto id :path.pathTo(t)) {
                    out(" "), out(sg->name(id)), hh;
                }
            }
            else {
                out("Not connected");
            }
        }
        else {
            out("Not in dataBase.");
        }
        hh;
    }
}


void testSymbolGraph()
{
    //degreeOfSeparation("routes.txt", "JFK",' ');
    degreeOfSeparation("movies.txt", "Tin Men (1987)",'/');
}

routes.txt

LAX LAS PHX
LAS PHX DEN
PHX DEN ORD DFW
DEN ORD
ORD DFW HOU ATL JFK
DFW HOU
HOU ATL MCO
ATL MCO JFK
MCO JFK

示例

在这里插入图片描述

文本下载movies.txt

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值