google 排列组合java_[经典算法] 排列组合-N元素集合的M元素子集

题目说明:

假设有个集合拥有n个元素,任意的从集合中取出m个元素,则这m个元素所形成的可能子集有那些?

题目解析:

假设有5个元素的集合,取出3个元素的可能子集如下:

{1 2 3}、{1 2 4 }、{1 2 5}、{1 3 4}、{1 3 5}、{1 4 5}、{2 3 4}、{2 3 5}、{2 4 5}、{3 4 5}

这些子集已经使用字典顺序排列,如此才可以观察出一些规则:如果最右一个元素小于m,则如上面一样的不断加1

如果右边一位已至最大值,则加1的位置往左移

每次加1的位置往左移后,必须重新调整右边的元素为递减顺序

所以关键点就在于哪一个位置必须进行加1的动作,到底是最右一个位置要加1?还是其它的位置?

在实际撰写程式时,可以使用一个变数positon来记录加1的位置,position的初值设定为n-1,因为我们要使用队列,而最右边的索引值为最大的n-1,在position位置的值若小于m就不断加1,如果等于m了,position就减1,也就是往左移一个位置;由于位置左移后,右边的元素会经过调整,所以我们必须检查最右边的元素是否小于m,如果是,则position调整回n-1,如果不是,则positon维持不变。

程序代码:

#include

using namespacestd;void ShowResult(int data[], intM)

{for (int i=0; i

{

cout<< data[i] << " ";

}

cout<

}int GenerateMFromN(int N, intM)

{int nCount = 0;if (M==0)

{return 1;

}int* State = new int[M];for (int i=0; i

{

State[i]= i+1;

}

nCount++;

ShowResult(State, M);int nPos = M-1;while (State[0] < N-M+1)

{if (State[M-1] ==N)

{

nPos--;

}else{

nPos= M-1;

}

State[nPos]++;for (int i = nPos+1; i < M; i++)

{

State[i]= State[i-1] + 1;

}

ShowResult(State, M);

nCount++;

}delete[] State;returnnCount;

}

TEST(Algo, tGenerateMFromN)

{//3选0组合 3!/(0!*(3)!) = 1

ASSERT_EQ(GenerateMFromN(3,0), 1);//5选3组合 5!/(3!*(5-3)!) = 10

ASSERT_EQ(GenerateMFromN(5,3), 10);//5选5组合 5!/(5!*8!) = 1

ASSERT_EQ(GenerateMFromN(5,5), 1);//10选2组合 10!/(2!*8!) = 45

ASSERT_EQ(GenerateMFromN(10,2), 45);

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值