计数法的组合的算法

// Copyright (C) 2004 BenBear
//
// This file is an algorithm of combination.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,

#include <iostream>
#include <cstdlib>
using namespace std;

template <typename BiIter>
inline void
__combi_reverse (BiIter first, BiIter last)
{
    reverse (first, last);
}

template <typename BiIter>
bool
next_combination_count (BiIter first, BiIter last)
{
    if (first == last)
        return false;
   
    BiIter i = last;
    if (--i == first)
        return false;
   
    if (*i-- == 0)
    {
        while ((i != first) && (*i == 0))
            --i;
        if (*i == 0)
            return false;
        BiIter j = i;
        iter_swap (i, ++j);
        return true;
    }
   
    while ((i != first) && (*i == 1))
        --i;
   
    if (i == first)
    {
        if (*i == 0)
            iter_swap (first, --last);
        return false;
    }
   
    BiIter ii = i;
    while ((--ii != first) && (*ii == 0))
        ;
    if (*ii == 0)
    {
        __combi_reverse (first, last);
        return false;
    }
   
    BiIter jj = ii;
    iter_swap (ii, ++jj);
    __combi_reverse (++jj, last);
    return true;
}

template <typename BiIter>
bool
prev_combination_count (BiIter first, BiIter last)
{
    if (first == last)
        return false;
   
    BiIter i = last;
    if (--i == first)
        return false;
   
    while ((i != first) && (*i == 0))
        --i;
    if (i == first)
    {
        if (*i == 1)
            iter_swap (first, --last);
        return false;
    }
   
    BiIter j = i;
    --j;
    if (*j == 0)
    {
        iter_swap (i, j);
        return true;
    }
   
    while ((--j != first) && (*j == 1))
        ;
    if (*j == 1)
    {
        __combi_reverse (first, last);
        return false;
    }
   
    BiIter jj = j;
    iter_swap (j, ++jj);
    __combi_reverse (++jj, last);
    return true;
}

//  for test
int main()
{
    const int N = 7;
    int a[N];
    int b[N] = {0};
    int n = 3;
    for (int i = 0; i < N; ++i)
        a[i] = i+1;
    for (int i = 0; i < n; ++i)
        b[N-1-i] = 1;
    do
    {
        for (int i = 0; i < N; ++i)
            if (b[i] == 1)
                printf ("%d", a[i]);
        printf ("/n");
    }
    while (prev_combination_count (b, b+N));
   
    system ("pause");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值