程序最美(寻路)

你还在坚持练习你的技术吗?运动员天天训练,音乐家也会演练更难的曲章。你呢?

封装的意义

封装的意义

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

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);

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

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

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

posted on 2013-06-30 22:45  unixfy  阅读(756)  评论(0编辑  收藏  举报

导航