封装的意义

封装的意义

前面《组合序列、排列序列的生成实现》中,我们在最后讨论了如何对组合序列生成函数、排列序列生成函数进行封装,组合序列生成函数定义如下:

void comb(const vector<int>& arr, int beg, int m, vector<vector<int> >& coms, vector<int>& tmp, int& total)

{

    if (m > arr.size() - beg)

    {

        return;

    }

    if (m == 0)

    {

        coms.push_back(tmp);

        ++total;

    }

    else

    {

        tmp.push_back(arr[beg]);

        comb(arr, beg+1, m-1, coms, tmp, total);

        tmp.pop_back();

        

        comb(arr, beg+1, m, coms, tmp, total);

    }

}

          组合函数调用如下:

                          comb(arr, 0, 4, coms, tmp, total);

根据定义和调用,我们发现组合函数定义中,第二个参数int beg只有在定义的时候才能用到,以方便其自身的调用,而对于实际调用没有任何作用,只要是对comb调用,beg的值都要为0。

所以,我们对comb函数封装如下:

// 封装组合

void comb_pack(const vector<int>& arr, int m, vector<vector<int> >& coms, vector<int>& tmp, int& total)

{

    coms.clear();

    tmp.clear();

    total = 0;

    comb(arr, 0, m, coms, tmp, total);

}

         我们对封装后的函数comb_pack调用如下:

                        comb_pack(arr, 4, coms, tmp, total);

         同样地,我们对排列序列生成函数进行封装。

void

perm(

  const vector<int>& arr_

, int n

, int beg

, vector<vector<int> >& pers

, vector<int>& tmp

, int& total

)

{

    static vector<int> arr(arr_);

    if (n == 0)

    {

        pers.push_back(tmp);

        ++total;

    }

    for (int i = beg; i != arr.size(); ++i)

    {

        exchange(arr[beg], arr[i]);

        tmp.push_back(arr[beg]);

        perm(arr, n-1, beg+1, pers, tmp, total);

        tmp.pop_back();

        exchange(arr[beg], arr[i]);

    }

}

         之前的调用形式为:

                        perm(arr, 3, 0, perm, tmp, total);

         对perm函数进行封装如下:

// 排列封装

void perm_pack(const vector<int>& arr, int n, vector<vector<> >& pers, vector<int>& tmp, int& total)

{

    pers.clear();

    tmp.clear();

    total = 0;

    perm(arr, n, 0, pers, tmp, total);

}

         对封装函数perm_pack的调用如下:

                        perm_pack(arr, 3, pers, tmp, total);

         全排列函数的封装如下:

// 全排列封装

void perm_full_pack(const vector<int>& arr, vector<vector<> >& pers, vector<int>& tmp, int& total)

{

    pers.clear();

    tmp.clear();

    total = 0;

    perm(arr, arr.size(), 0, pers, tmp, total);

}

         全排列封装函数的调用为:

                        perm_full_pack(arr, pers, tmp, total);

         我们可以从对组合序列和排列序列的生成函数进行封装,可以看到封装后的函数少了一些不必要的参数,使得函数更为简介明了,并且在使用的时候避免犯传参方面的错误。

         被封装的函数由于需要对其自身的调用,所以需要一些参数记录其递归层次。通过一步的封装,使得我们的函数把不需要的参数隐蔽起来,这样代码看起来更为友好。

         封装可以使得函数接口更为简约,通过添加一个封装层使得定义层与调用层隔离,降低定义与调用之间的耦合性,提高定义和调用模板各自的内聚性。

你可能感兴趣的:(封装)