[英]How to convert vector<pair<string, T>> to vector<pair<string,string>>
我有一個方法需要我返回一個向量<pair<string, string>>。 但是,我的輸入是向量<pair<string, T>>
。 這是返回圖中邊數的更大問題的一部分。 相關代碼在下面,其中T
是 integer 類型。
map<string, string> all_vertices;
map<string, map<string, T>> adj_list;
template<typename T>
size_t Graph<T>::num_edges() {
int edge_num = 0;
for(auto& node : adj_list) {
for(auto& edge : node.second) {
edge_num++;
}
}
return edge_num / 2;
}
template<typename T>
void Graph<T>::add_edge(const string& u, const string& v, const T& weight) {
if(!adjacent(u, v)) {
if(adj_list[u].find(v) == adj_list[u].end()) {
adj_list[u].insert({v, weight});
adj_list[v].insert({u, weight});
}
}
}
template <typename T>
void Graph<T>::add_vertex(const string& u) {
if(!contains(u)){
all_vertices.insert({u,u});
adj_list[u]= map<string, T>();
}
}
template <typename T>
bool Graph<T>::adjacent(const string& u, const string& v) {
if(contains(u) && contains(v)){
if (adj_list[u].find(v)!=adj_list[u].end()){
return true;
}
}
return false;
}
template<typename T>
vector<pair<string, string>> Graph<T>::get_edges() {
vector<pair<string, T>> e;
vector<pair<string, string>> e_string;
for(auto x1 : adj_list) {
for(auto x2 : x1.second) {
e.push_back(x2);
}
}
return e;
}
/* the test cases for the nodes in the graphs:
Number of vertices: 5
Number of edges: 8
Is vertex A in the graph? 1
Is vertex F in the graph? 0
Is there an edge between A and B? 1
Is there an edge between B and C? 0
*/
不同功能的說明:
vector<pair<string,string>> get_edges();
返回圖中所有邊的向量——每條邊由一對入射到邊上的頂點表示。
void add_edge(const string&, const string&, const T&);
向圖中添加加權邊——兩個字符串代表入射頂點; 第三個參數表示邊緣的權重。
我建議你跳過創建e
和 go 的中間步驟直接到e_string
。 另外,將get_edges()
const
,因為您沒有更改*this
。
使用std::to_string
將 integer T
轉換為std::string
。
然而,真正的問題是您的代碼嘗試僅添加一個頂點+ 每條邊的權重。
在您對問題的描述中,它說它應該是一對頂點。 它並沒有說應該包括重量。
所以,這是如何做到的:
template <typename T>
std::vector<std::pair<std::string, std::string>> Graph<T>::get_edges() const {
std::vector<std::pair<std::string, std::string>> e_string;
for (auto&[u, Map] : adj_list) {
// only add one direction, get all v's where u < v:
for(auto vw_it = Map.upper_bound(u); vw_it != Map.end(); ++vw_it) {
e_string.emplace_back(u, vw_it->first);
}
}
return e_string;
}
不相關的建議:
您可以簡化num_edges()
方法(也應該是const
)。 您現在遍歷內部map
中的所有元素來計算它們,但是map
有一個size()
成員 function,所以這不是必需的:
#include <numeric> // std::accumulate
template<typename T>
size_t Graph<T>::num_edges() const {
return
std::accumulate(adj_list.begin(), adj_list.end(), size_t{0},
[](size_t sum, const auto& node) {
return sum + node.second.size();
}) / 2;
}
在add_edge
,您可以跳過檢查連接是否已經存在並嘗試添加它。 如果它是重復的,它將被拒絕:
template<typename T>
void Graph<T>::add_edge(const std::string& u, const std::string& v,
const T& weight)
{
if(u == v) return; // don't allow linking a vertex with itself
adj_list[u].emplace(v, weight);
adj_list[v].emplace(u, weight);
}
您可能仍希望擁有adjacent
的 function。 在這種情況下,我會將其簡化為以下內容:
template <typename T>
bool Graph<T>::adjacent(const string& u, const string& v) const {
auto it = adj_list.find(u);
return it != adj_list.end() && it->second.find(v) != it->second.end();
// return it != adj_list.end() && it->second.contains(v); // C++20
}
另一種可能的解決方案是在不過多修改代碼的情況下將 T 轉換為輸入字符串。
#include <iostream>
#include <vector>
#include <string>
#include <map>
using std::vector;
using std::string;
using std::map;
using std::pair;
map<string, string> all_vertices;
template <typename T>
map<string, map<string, T>> adj_list;
template <typename T>
vector<pair<string, string>> Graph<T>::get_edges() const {
vector<pair<string, T>> e;
for (auto x1 : adj_list<T>) {
for (auto x2 : x1.second) {
e.push_back(x2);
}
}
return e;
}
// Graph<string> g;
// vector<pair<string, string>> edges = g.get_edges();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.