C++ C++;:最优复杂度函数

C++ C++;:最优复杂度函数,c++,stl,time-complexity,C++,Stl,Time Complexity,我在一次采访中被问到一个问题: 我们的软件包如下(软件系统组件中的软件包)- pkg1->pkg2、pkg3、pkg4 pkg2->pkg5、pkg6 pkg7->pkg8,pkg9 pkg9->pkg10,pkg11 其中,Pkg1依赖于pkg2,3,4 pkg2依赖于pkg5、6等 这些包将被构建(编译)。可以并行构建独立的包,以实现最快的编译 编写一个C++函数,列出独立的包和相关包,尽可能好的时间复杂度。由您自行设计函数签名,因此您可以选择输入包数据的容器 输出(在标准输出上)—— 独立

我在一次采访中被问到一个问题:

我们的软件包如下(软件系统组件中的软件包)-

pkg1->pkg2、pkg3、pkg4

pkg2->pkg5、pkg6

pkg7->pkg8,pkg9

pkg9->pkg10,pkg11

其中,Pkg1依赖于pkg2,3,4

pkg2依赖于pkg5、6等

这些包将被构建(编译)。可以并行构建独立的包,以实现最快的编译

编写一个C++函数,列出独立的包和相关包,尽可能好的时间复杂度。由您自行设计函数签名,因此您可以选择输入包数据的容器

输出(在标准输出上)—— 独立软件包-pkg3、pkg4、pkg5、pkg6、pkg8、pkg10、pkg11 依赖包-pkg1、pkg2、pkg7、pkg9


在我的解决方案中,我对输入包使用std::map,对依赖包和独立包分别使用std::set和std::vector

我可以实现的时间复杂度是O(mn),其中m是依赖包的数量,n是独立包的数量。 我们能做到更多吗?怎么用?感谢您的帮助/指导

提前谢谢

编辑1: 我想,我将在这里给出我的实现-

#include <iostream>
void filterPackages(const std::map<int, std::vector<int> > &packages)
{
    std::vector<int> potential_independent_packages;
    std::set<int> dependent_packages;

    for(auto iter : packages)
    {
        dependent_packages.insert(iter.first);
        for(auto iter1 : iter.second)
        {
            potential_independent_packages.push_back(iter1);
        }
    }

    std::cout<<"Independent package - ";
    for( auto iter2 : potential_independent_packages)
    {
        if(dependent_packages.found(iter2) == std::set::end)
        {
            std::cout<<iter2;
        }
    }

    std::cout<<std::endl<<"Dependent packages - ";
    for( auto iter3 : dependent_packages)
    {
        std::cout<<iter3;
    }
}
#包括
无效过滤器包(常量标准::映射和包)
{
std::向量势_独立_包;
std::设置依赖的_包;
用于(自动iter:包)
{
相关包插入(iter第一);
用于(自动iter1:iter.秒)
{
潜在的独立软件包。推回(iter1);
}
}

std::cout描述中没有明确说明,但我想您的意思是,如果它所依赖的某些包尚未编译,则无法编译该包

根据这个假设,有一个相当简单的代码可以优化编译顺序。计算每个包的依赖深度,然后在并行包中编译 相同深度,从最低深度的包装开始

(什么是“依赖深度”?将依赖视为有向树, 然后,元素的深度是从元素到它所依赖的叶子的最长路径。形式上,如果包没有依赖项,则其深度为零,而对于其他包,深度[package]=max(depth[dependens_of the_package])+1。请注意,具有相同深度的包必须相互独立)

我将使用以下代码

class PackageOptimizer
{
    public:
    struct PackageDependency
    {  
        size_t Count() const
        {
            return m_end - m_begin;
        }
        size_t m_begin;
        size_t m_end;
    };

    vector<size_t> FindLeaves()
    {
        vector<size_t> leaves;
        for(size_t i = 0; i<m_deps.size(); i++)
        {
            if(m_deps[i].m_begin == m_deps[i].m_end)
                leaves.push_back(i);
        }

        return leaves;
    }

    vector<int> ComputeDepthMap()
    {
        vector<int> Depth(m_deps.size());
        vector<int> Count(m_deps.size(),0);
        vector<size_t> currSet = FindLeaves();
        vector<size_t> nextSet;

        int currDepth = 0;
        while(!currSet.empty())
        {
           for(size_t elem : currSet)
           {
               Depth[elem] = currDepth;

               for( size_t  upPackage = m_depsInv[elem].m_begin;
                            upPackage < m_depsInv[elem].m_end; 
                            upPackage++)
                {
                    Count[upPackage]++;

                    if(Count[upPackage] == m_deps[upPackage].Count())
                    {
                        nextSet.push_back(upPackage);
                    }
                }
           } 
           swap(nextSet, currSet);
           currDepth++;
           nextSet.clear();
        }

        return Depth;
    }

    private:
    // package i is dependent on
    // m_indices[m_deps[i].m_begin], m_indices[m_deps[i].m_begin+1], ... m_indices[m_deps[i].m_end-1]
    vector<PackageDependency>   m_deps; 
    vector<size_t>              m_indices;

    // following packages are dependant on package i
    // m_indicesInv[m_depsInv[i].m_begin], m_indicesInv[m_depsInv[i].m_begin+1], ... m_indicesInv[m_deps[i].m_end-1]
    vector<PackageDependency>   m_depsInv; 
    vector<size_t>              m_indicesInv;
};
class-PackageOptimizer
{
公众:
结构包依赖项
{  
大小\u t计数()常数
{
返回m_end-m_begin;
}
开始时的大小;
尺寸m__u端;
};
向量FindLeaves()
{
向量叶;

对于(sisixt t=0;在各种C++标准容器实现中的操作时间复杂度已经很好,您应该先引用这里,这里的问题是非常模糊的。什么是优化的限制变量?包的总数?只有没有任何依赖性的包应该是CO。未测试为
独立的
?没有依赖项的包是否显示在输入映射的键中,或者它们的名称/编号是否必须从其他包的依赖项中收集?输出是否需要按包名称/编号排序?我真的可以选择任何输入结构吗?我可以要求输入为类似包含的
映射可以列出
O(n)中所有值的er
时间以及它们是否显示为键。要回答用户10605163的有效问题-包的总数?-假设为100秒,只有完全没有依赖关系的包才被视为独立的包?-是的,没有依赖关系的包是否显示在输入映射的键中,或者是否必须收集它们的名称/编号om其他软件包的依赖关系?是的,没有依赖关系的软件包必须从依赖关系中收集。其本质是选择最佳的输入数据结构。输出是否需要按软件包名称/编号排序?否,我真的可以选择任何输入结构吗?我可以要求输入是一个类似于地图的容器,可以列出O(n)时间内的所有值,以及它们是否显示为键。-是的,这是您的函数,因此您可以选择并发布签名。我也选择了std::map。您的代码实际上是
O(n*m*lnm)
最坏情况,其中n是总包数,m是依赖包数,如果所有依赖包依赖于所有其他包。那么
潜在的独立包
的大小将为
n*m
,您将为每个独立包检查
依赖包
的系数
ln(m)
。您还可能多次打印软件包。