我有一个成对的列表,每对都有两个整数值。 如何将这对对转换为包含类似于以下edge []中显示的边数组的对象?我已经创建了一个Graph类,但是为了使用它,我需要这些对,它们将是我的边缘,被转换为一个数组数组,其中数组中的每个数组将容纳一对两个整数值。
这是我的列表,其中包含成对的整数值:
list<pair<unsigned int, unsigned int> > myList;
这是我创建的用于容纳两个边缘的结构:
struct Edge {
int source
int destination;
};
这个边缘数组是我希望将对对转换为的示例:
Edge edges[] =
{
{ 0, 1 }, { 1, 2 }, { 2, 0 }, { 2, 1 }
};
如果我需要对问题的特定部分更加具体,请让我知道,我将很乐于阐述。谢谢
答案 0 :(得分:1)
OP在评论中回答了有关可能的实现方式的其他答案。
在原始问题中说:
list<pair<unsigned int, unsigned int> > myList;
我认为OP的想法是拥有一种持有价值观的结构,这是一种合理的方法。我们有一个图,该图包含多个边。非常合理。
因此,让我们定义一个Graph类,然后添加一个边数组。但是由于我们使用的是C ++,因此我们不会使用普通的C-Style数组,而是使用std::vector
。
如果我们使用struct Edge的向量,则可以使用与列表相同的方式:
std::vector<Edge> sameAsList{ { 0U, 1U }, { 1U, 2U }, { 2U, 0U }, { 2U, 1U } };
即使将原始列表封装在Graph类中,我们也可以轻松地将其转换为此类向量。有许多可能的实现。我展示了可能最受欢迎的3个版本。
std::transform
进行翻译。也许是“更现代的” C ++解决方案请参阅
#include <vector>
#include <list>
#include <utility>
#include <algorithm>
#include <iostream>
#include <iterator>
// Define aliases. To make reading easier
using PairOfUint = std::pair<unsigned int, unsigned int>;
using ListOfPairs = std::list<PairOfUint>;
// Our struct for edges
struct Edge {
Edge() {}
Edge(unsigned int s, unsigned int d) : source(s), destination(d) {}
friend std::ostream& operator << (std::ostream& os, const Edge& e) { return os << e.source << " " << e.destination; }
unsigned int source{};
unsigned int destination{};
};
class Graph
{
public:
Graph() : edges() {}
// 3 differnt conversion functions from list of pair to vector of struct. All have the same result
void add1(ListOfPairs& lop);
void add2(ListOfPairs& lop);
void add3(ListOfPairs& lop);
// Reset edges vector to empty
void clearEdges() { edges.clear(); }
// Inserter. For this example, just print edges
friend std::ostream& operator << (std::ostream& os, const Graph& g) {
std::copy(g.edges.begin(), g.edges.end(), std::ostream_iterator<Edge>(os, "\n")); return os;
}
protected:
std::vector<Edge> edges{};
};
void Graph::add1(ListOfPairs& lop)
{
for (ListOfPairs::const_iterator cIterLop = lop.cbegin(); cIterLop != lop.cend(); ++cIterLop)
edges.emplace_back(Edge(cIterLop->first, cIterLop->second));
}
void Graph::add2(ListOfPairs& lop)
{
for (const PairOfUint& poui : lop)
edges.emplace_back(Edge(poui.first, poui.second));
}
void Graph::add3(ListOfPairs& lop)
{
std::transform(lop.begin(), lop.end(), std::back_inserter(edges), [](const PairOfUint & poui) {
return Edge(poui.first, poui.second); });
}
ListOfPairs myList{ { 0U, 1U }, { 1U, 2U }, { 2U, 0U }, { 2U, 1U } };
int main()
{
Graph graph{};
graph.add1(myList);
std::cout << "\nVersion1 with iterators:\n" << graph;
graph.clearEdges();
graph.add2(myList);
std::cout << "\n\nVersion2 with range based for:\n" << graph;
graph.clearEdges();
graph.add3(myList);
std::cout << "\n\nVersion3 with std::transform for:\n" << graph;
return 0;
}
答案 1 :(得分:0)
您为什么不使用向量呢?它们只是动态数组。
您可以做这样的事情。
class Edge
{
public:
//your 2d array. you can access values by doing edges[x][y]
std::vector< std::vector<unsigned int> > edges;
//To initialize you could create a constructor like this
Edge(list<pair<unsigned int, unsigned int> > myList)
{
while(myList.size() > 0)
{
vector<unsigned int> temp;
temp.push_back(myList.front().first);
temp.push_back(myList.front().second);
edges.push_back(temp);
myList.pop_front();
}
}
}
我没有做任何封装,只是分享了创建对象的想法。
答案 2 :(得分:0)
PaulMcKenzie的评论似乎是最好的解决方案,而不是维护两个容器(std :: list和array / vector),您只能使用std::vector<Edge>
。
std::vector <Edge> vec{ { 0, 1 },{ 1, 2 },{ 2, 0 },{ 2, 1 } };
int main() {
std::cout << vec[0].source << " " << vec[0].destination ;
for (auto e : vec) {
e.source = e.destination = 0;
}
}