首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

自创的非递归产生所有组合的C+代码

记得上次有一回是在刷牛客网题目。。。刷着刷着就做到了递归类型训练,结果呢。。。

不言而喻,呼应这个题目的是,用递归方法求1~a范围内所有组合。。。。。

嗯,虽然两个三个好求一些,但是a个。。。。还是算了,本人之上本来就不怎么够使。。。。。

后来想想吧,要是玛德练了半天C++连个组合数都求得费劲,还能干点儿啥呢。。。。

于是乎就想了想STL标准算法肯定也比自己写的高效n倍,抱着试试的心态我上网上搜了搜,结果看到了下边这几个:

可以检查两两向量之间是不是有重复元素,下边解释

已经很接近取1\2\3个随机数的概念了

对取出来的1\2\3个数的组合进行排列(实际上没啥用)

实际上这个vector才是精髓所在,二维vector跟二位迭代器就可以把第一维的vector设置成取n个数形成组合的时候的组合数,第二维就是n,外边的话就可以在1到5之间循环了。。。。

可是这就有个问题,俩取出来的随机数不可能总一样吧,俩向量之间也不可能总一样吧。。。。。

讲实话这个问题当时真的差点儿把我卡死,直到有那么俩小时脑袋开了窍---没必要非用迭代器访问vector。。。。。

更没必要非得用generate_n函数。。。。(当初用generate_n主要是因为其中一个参数就是vector类型的,用着特方便,结果呢呵呵。。。。。

于是乎就成了下边这样:

1、每第二维的vector必须在内部消除相同元素

2、每第一维内的所有向量之间还要两两比较,不能有相同的向量(实际上这部分设计成函数的话还是要用1里的遍历方式

于是乎就产生了下边这样个代码:

#include

#include

#include

#include

#include

using namespace std;

int fact(int n){

 int i, f=1;

 for(i=1;i

     f=f*i;

 return f;

}

int zuheshu(int m,int n){

 if(m

     int tem = 0;

     tem = m;

     m = n;

     n = tem;

 }

 int h = fact(m)/(fact(n)*fact(m-n));

 return h;

}

int traverseVector_2(vector v1,vector v2,int tt){

 vector::iterator it1;

 vector::iterator it2;

 int th = 0;

 for(it1 = v1.begin(); it1 != v1.end(); ++it1){

     for(it2 = v2.begin(); it2 != v2.end(); ++it2){

         if((*it1)==(*it2)){//至少有一个元素不一样菜证明两个向量不一样,相同的元素个数直接等于vector长度的话就证明俩向量是一样的

             th++;

         }else{

         }

     }

 }

 if(th == tt){

     return 1;

 }else{

     return 0;

 }

}

int main() {

 for(int tn = 0;tn < 5;tn++){

     int tnn = tn + 1;

     int thy = zuheshu(5,tnn);//tnn是确保不会变成n中取0个数的情况

     vector re(thy);//取tnn个数时候的组合数,初始化第一个维度

     for(int gh = 0;gh < thy;gh++){

         re[gh].resize(tnn);//遍历第一个维度,初始化第二个维度上的所有子vector

     }

 srand((int)time(NULL));//设置系统时间为随机数种子,避免产生随机数的大规模一致化

     for(int gh = 0;gh < thy;gh++){//访问vector第一维

         for(int t = 0;t < tnn;t++){//访问vector第二维

             re[gh][t] = rand()%5 + 1;//确保生成的随机数永远大于等于1且不超过5

             for(int T = 0;T

                 if(re[gh][t] == re[gh][T]){

                     t--;//如果该向量内有俩元素相同,返回上一位从新生成

                 }

             }

         }

         for(int gm = 0;gm < gh;gm++){

             if(traverseVector_2(re[gh],re[gm],tnn)){

                 gh = 0;//如果发现两个向量内容一样(不包括顺序)直接清零从新生成

             }else{

             }

         }

     }

     vector::iterator iter;//定义一个二维向量迭代器

     for (iter = re.begin(); iter != re.end() ; ++iter) {

         for (int i = 0; i < (*iter).size(); ++i) {//从迭代器的维度去访问迭代器的每一位

             cout

         }

         cout

     }

     cout

 }

return 0;

}

有人会问写这么长的就为了产生个组合数?太垃圾了吧。。。。。

确实是很垃圾,如果真不是为了逃避递归调用这个魔鬼(原谅我的懒吧)。。。。。

至于效果则是这样的:

选取里边一个数,有多少种组合

选取里边两个数的所有组合

选取里边三个数的所有组合

选取里边四个以及五个数分别的所有组合

实际上上边这些都是一张照片,别误会。

下边是不同循环下的其他情况:

6取1

6取2

6取3

6取4、6取5、6取6

但是发现这样的效率还是太低了。。。。。

这只是个闲的没事儿的作品啊,没任何目的性,广大朋友勿喷。。。。。。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20210105A08CNM00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

相关快讯

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券