C++ 创建自定义图形数据结构是否违反任何原则?

C++ 创建自定义图形数据结构是否违反任何原则?,c++,data-structures,theory,C++,Data Structures,Theory,我正在做一个小的科学课程项目,与使用连续方法进行电路测试有关。该程序将解析电路定义文件,然后构建一个易于修改的表示电路的图形结构。然后对该图形进行某些修改,并对其进行拓扑排序。排序后,图形将转换为静态结构,该结构由数组列表组成,其中每个数组都对应于某个拓扑排序度。之后,可以很容易地模拟电路,因为您可以依赖排序顺序并按顺序处理模型 这一切都很好,符合逻辑,但我提到的两个图是自定义数据结构,它们是: 1) 不完全按照STL规范构建(对我来说,这将是漫长而困难的-图形比向量和列表复杂得多) 2) 对于

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

这一切都很好,符合逻辑,但我提到的两个图是自定义数据结构,它们是:

1) 不完全按照STL规范构建(对我来说,这将是漫长而困难的-图形比向量和列表复杂得多)

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

3) 可用于我的图形的操作集是有限的,它反映了我的项目的需要

4) 代码很简单

现在我只是一名IT专业的三年级学生,在完成了软件设计课程并阅读了一些现实生活中的代码之后,我想知道:

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

2) 我对数据结构的假设是否违反了软件设计的数千条原则

3) 对于我在本项目和未来项目中创建的所有数据结构,我真的应该始终遵守STL规范吗

此项目采用C+++</P> 谢谢你的关注!对于这些问题,我希望能有一个基本的、理论上的答案,以及一个解决这个问题的实际方法的例子。

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

不仅可以,而且应该如此。代码不需要复杂

2)我对数据结构做出假设是否违反了软件设计的数千条原则?

嗯,你怎么能不这样做呢。这个问题对我来说没有意义

3)对于我在本项目和未来项目中创建的所有数据结构,我真的应该始终遵守STL规范吗?

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

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

不仅可以,而且应该如此。代码不需要复杂

2)我对数据结构做出假设是否违反了软件设计的数千条原则?

嗯,你怎么能不这样做呢。这个问题对我来说没有意义

3)对于我在本项目和未来项目中创建的所有数据结构,我真的应该始终遵守STL规范吗?


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

我认为这样简单的设计没有什么错:

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));
    }
};
它保持简单、模块化,并允许您在其上使用标准库。它允许您在节点和边上进行迭代。如果需要顶点的邻接列表,则必须在整个边列表上循环,但这是经过设计的(如果要快速执行,则需要更好的结构)

例如,define(不幸的是,这个不是标准的)

迭代
某个节点的邻接列表


有了C++0x,就有了更优雅的方法来编写这样的算法(使用lambdas)。

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

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));
    }
};
它保持简单、模块化,并允许您在其上使用标准库。它允许您在节点和边上进行迭代。如果需要顶点的邻接列表,则必须在整个边列表上循环,但这是经过设计的(如果要快速执行,则需要更好的结构)

例如,define(不幸的是,这个不是标准的)

迭代
某个节点的邻接列表


使用C++0x有更优雅的方法来编写此类算法(使用lambdas)。

请不要给它一个家庭作业标签。尊重他人,谢谢。你如何表示第一张图?可以使用标准容器构建邻接列表或类似结构。你也看过boost::graph数据结构吗?IIRC它就像一个顶点列表和一个边列表,边知道它们连接的顶点。因此,您可以快速插入/删除数据。是的,我知道Boost,但由于这是一个大学项目,我的目标是演示我可以编写代码,而不是使用现有的解决方案。如果我选择使用Boost::Graph和其他库,那么我的代码就很少了。请不要给它一个家庭作业标签。尊重他人,谢谢。你如何表示第一张图?可以使用标准容器构建邻接列表或类似结构。你也看过boost::graph数据结构吗?IIRC它就像一个顶点列表和一个边列表,边知道它们连接的顶点。因此,您可以快速插入/删除数据。是的,我知道Boost,但由于这是一个大学项目,我的目标是演示我可以编写代码,而不是使用现有的解决方案。如果我选择使用Boost::Graph和其他库,那么我的代码就很少了。我的缺点是,在第2点中,我主要指的是代码应该更通用、更少定制的想法,或者类似的想法,我们在学校学到的东西。@Semen设计真正的通用代码是非常非常困难的。即使是C++标准库也需要数年才能达到其目前(仍不理想)的状态。你应该正确而清晰地设计你的代码,以满足你当前的需求
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));