2011-05-03 64 views
0

我正在使用连续方法开展与电路测试相关的小型科学课程项目。该程序将解析电路定义文件,然后构建一个易于修改的图形结构来表示电路。然后对该图进行某些修改,并对其进行拓扑排序。排序后,图形转换为一个由数组列表构成的静态结构,每个数组对应一定的拓扑排序程度。之后,可以很容易地模拟电路,因为您可以依赖排序顺序并按顺序处理模型。创建自定义图形数据结构是否违反任何原则?

现在是所有好的和逻辑,但我所提到的两个图是自定义的数据结构,其中:

1)不建挺到STL规范(是漫长和艰难的,我反正 - 图比向量和列表复杂得多)

2)对于第二个图,我假设它是不可修改的,并使用矢量向量或向量列表来获得速度。

3)我的图表可用的一组操作是有限的,反映了我的项目需求。

4)代码很简单。

现在我只是一个三年级学生的IT和软件设计和阅读一些现实生活中的代码后,成就了一个疗程后,我在想:

1)能够(或者甚至可能)的代码如此简单?

2)不要因为假设数据结构而违反软件设计的数以千计的原则吗?

3)我应该真的总是符合我在这个和未来的项目中创建的所有数据结构的STL规范吗?

该项目使用C++。

感谢您的关注!我希望对这些问题有一个基本的和理论上的答案,以及这个问题的实际解决方案的例子。

+0

请不要给这个作业标签。恭敬谢谢。 – iksemyonov 2011-05-03 14:10:41

+1

你如何表示第一个图?邻接列表或类似结构可以用标准容器构建。你还看看boost :: graph数据结构吗? – 2011-05-03 14:13:15

+0

IIRC它就像顶点列表和边缘列表,边缘知道它们连接的顶点。所以你可以快速插入/删除数据。是的,我了解Boost,但由于这是一个大学项目,我的目标是证明我可以编写代码,而不是使用已有的解决方案。如果我选择使用Boost :: Graph和其他库,那么我的代码会很少。 – iksemyonov 2011-05-03 14:44:42

回答

5

1)可以(甚至可以)代码简单吗?

不仅可以,它应该是。代码不需要很复杂。

2)不要因为假设数据结构而违反数以千计的软件设计原则吗?

恩,你会怎么做。这个问题对我没有意义。

3)我应该真的总是遵从STL规范来说明我在这个和未来的项目中创建的所有数据结构吗?

没有。例如,如果您不需要迭代结构,则不要提供迭代器。只实现你实际需要的东西。

+0

那么我的不好,在第2点)我主要是指代码应该更通用,更少定制,或类似的东西,我们在学校教过的想法。 – iksemyonov 2011-05-03 14:46:24

+0

@Semen设计真正的通用代码非常非常困难。即使是C++标准库也需要花费数年时间才能达到目前的状态(仍然不太理想)。您应该设计自己的代码,以正确,明确地满足您当前的要求。 – 2011-05-03 14:49:25

1

我认为没有错用一个简单的设计是这样的:

typedef int node_type; // or a more complex type here 
typedef std::list<node_type> node_list; 
typedef std::pair<node_list::const_iterator, node_list::const_iterator> edge_type; 
typedef std::list<edge_type> edge_list; 

struct graph 
{ 
    node_list nodes; 
    edge_list edges; 

    // Some member functions for doing specific things here 
    // for instance: 
    void remove_node(node_list::iterator i) 
    { 
     nodes.erase(i); 
     edges.remove_if(connects(i)); 
    } 
}; 

其中

struct connects 
{ 
    connects(node_list::const_iterator i) : i(i) {} 

    bool operator()(const edge_type& e) const 
    { 
     return e.first == i || e.second == i; 
    } 

private: 
    node_list::const_iterator i; 
}; 

它保持简单,模块化,并允许您使用标准库就可以了。它允许你迭代节点和边。如果你想要一个顶点的邻接列表,你将不得不遍历整个边界列表,但这是设计的(如果你想快速完成这个,你需要一个更好的结构)。

例如,定义(这个人是不幸的是没有标准)

template <typename I, typename F, typename G> 
F for_each_if(I first, I last, F f, G pred) 
{ 
    for (; first!=last; ++first) if (pred(*first)) f(*first); 
    return f; 
} 

,现在你可以做

for_each_if(g.edges.begin(), g.edges.end(), something, connects(some_node)); 

遍历的some_node邻接表。

使用C++ 0x有更优雅的方法来编码这些算法(使用lambdas)。

+0

虽然这个设计看起来不是那么快,但它展示了一种不同的主题。我想我需要学习更多的C++ 0x和STL。我还没有习惯于功能风格的编码。 – iksemyonov 2011-05-04 10:49:16

+0

@Semen:的确,这样的方法使您能够为您的应用程序利用STL算法。然而,你很快就会意识到,STL算法真的很吸引,没有lambda函数。如果你有权访问C++ 0x编译器,那么可以随意使用这种方法。否则,对于一个简单的项目来说这可能太麻烦了。 – 2011-05-04 11:35:35

+0

这很巧妙!切换到C++ 0x对我的工作来说可能是一个很好的奖励,虽然我没有时间学习这个新技术。顺便说一下,它还没有标准化,请问你指点我一个体面的语言/ STL实施?请问G ++ 4.x分支是否工作? – iksemyonov 2011-05-04 14:05:51

相关问题