记得上次有一回是在刷牛客网题目。。。刷着刷着就做到了递归类型训练,结果呢。。。
不言而喻,呼应这个题目的是,用递归方法求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
但是发现这样的效率还是太低了。。。。。
这只是个闲的没事儿的作品啊,没任何目的性,广大朋友勿喷。。。。。。
领取专属 10元无门槛券
私享最新 技术干货