排列组合算法(非递归)
来源:互联网 发布:路由器关闭了所有网络 编辑:程序博客网 时间:2024/05/21 11:17
/************************
* 排列组合算法
* 非递归方式
*
* 编译器:borland c++
* 时间:2013-10-10
* 笔名:Jungle
*
*
* 说明:排列的核心算法来源:
* http://blog.csdn.net/hackbuteer1/article/details/6657435
* http://plutoblog.iteye.com/blog/976216
* http://blog.csdn.net/aipb2008/article/details/2227490
*
* 组合算法是自己设计的。
*
***********************/
#include <iostream>
using namespace std;
// 在[All]中选[Opt]的全排列
// 思路:先组合再全排列
#define swap(type,a,b) {type temb=a; a=b; b=temb;}
void Permutation(int *,int);
void Permutation_Combination(int All,int Opt); // 排列
// 在[All]中选[Opt]的所有组合
void Combination(int All,int Opt); // 组合
void main(void)
{
Permutation_Combination(6,3);
Combination(8,4);
cin.get();
cout<<"F i n i s h !"<<endl;
}
/*
非递归全排列算法
这个算法是C++ STL算法next_permutation的思想。
*/
void Permutation(int *a,int length)
{
int i,j;
while(1)
{
// 打印输出
for(i=0; i<length; ++i)
{ cout<<a[i]<<" "; }
cout<<endl;
cin.get();
// 后->前,找到【Ai<A(i+1)】的[i]位置
for(i=length-2; i>=0; --i)
{
if(a[i]<a[i+1])
{ break; }
else if(i==0) // 找不到升序的数据,全排列结束。
{ return; }
}
// 后->前,找到比【Aj>Ai】的[j]位置
for(j=length-1; j>i; --j)
{
if(a[j]>a[i])
{ break; }
}
// 交换位置i,j的值
swap(int,a[i],a[j]);
// 【(i+1)至结束位置】的所有数据逆序
i++;
j=length-1;
for(; i<j; ++i,--j)
{
swap(int,a[i],a[j]);
}
}
}
void Permutation_Combination(int All,int Opt)
{
if(All<Opt || Opt<2) { return; }
// 组合算法
int flag=0;
int *com=new int[Opt+1];
com[0]=1;
while(1)
{
if(com[flag] > (All-Opt+flag+1))
{
if(flag == 0)
{
delete []com;
return;
}
com[--flag]++;
}
else
{
if(flag == (Opt-1))
{
// 得到一个组合,是升序排列
// 进而求出该组合的全排列
int *per=new int[Opt];
for(int i=0;i<Opt;i++)
{
per[i]=com[i];
}
Permutation(per,Opt);
cout<<"------------"<<endl;
delete []per;
}
com[flag+1]=com[flag++]+1;
if(flag == Opt) { com[--flag]++; }
}
}
}
/*----------------------------------------------------------
非递归组合算法
说明:
以5选3为例,共10种组合,如下:
... 百--十--个 位的数据
... 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,
1.可以看出百位的数据<=3,十位的数据<=4,个位的数据<=5,
即每个位置上的值都有各自的范围。
2.组合中的数据总是升序的,因为数据都是由高位推出低位。
3.采用进位的思路,低位数据超出范围,高1位进位。
4.定义:个位称为最低位。
---------------------------------------------------------*/
void Combination(int All,int Opt)
{
int i;
int flag=0; // 当前位置标识
int *com=new int[Opt+1]; // 要求数组长度>=(Opt+1)
com[0]=1; // 初始化最高位
while(1)
{
// 当前位置的值溢出
if(com[flag] > (All-Opt+flag+1))
{
if(flag == 0)
{
delete []com;
return; // 最高位溢出则结束。
}
// 低位溢出,高1位进位。
com[--flag]++;
}
// 当前位置的值没有溢出
else
{
if(flag == (Opt-1))
{
// 位置标识指向个位时,得到一个组合,输出
for(i=0;i<Opt;i++)
{ cout<<com[i]<<' '; }
cout<<endl;
cin.get();
}
// 低位=高位+1
com[flag+1]=com[flag++]+1;
// 个位的低1位称为最最低位
// 位置标识指向最最低位时,个位上的数进位
if(flag == Opt) { com[--flag]++; }
}
}
}
* 排列组合算法
* 非递归方式
*
* 编译器:borland c++
* 时间:2013-10-10
* 笔名:Jungle
*
*
* 说明:排列的核心算法来源:
* http://blog.csdn.net/hackbuteer1/article/details/6657435
* http://plutoblog.iteye.com/blog/976216
* http://blog.csdn.net/aipb2008/article/details/2227490
*
* 组合算法是自己设计的。
*
***********************/
#include <iostream>
using namespace std;
// 在[All]中选[Opt]的全排列
// 思路:先组合再全排列
#define swap(type,a,b) {type temb=a; a=b; b=temb;}
void Permutation(int *,int);
void Permutation_Combination(int All,int Opt); // 排列
// 在[All]中选[Opt]的所有组合
void Combination(int All,int Opt); // 组合
void main(void)
{
Permutation_Combination(6,3);
Combination(8,4);
cin.get();
cout<<"F i n i s h !"<<endl;
}
/*
非递归全排列算法
这个算法是C++ STL算法next_permutation的思想。
*/
void Permutation(int *a,int length)
{
int i,j;
while(1)
{
// 打印输出
for(i=0; i<length; ++i)
{ cout<<a[i]<<" "; }
cout<<endl;
cin.get();
// 后->前,找到【Ai<A(i+1)】的[i]位置
for(i=length-2; i>=0; --i)
{
if(a[i]<a[i+1])
{ break; }
else if(i==0) // 找不到升序的数据,全排列结束。
{ return; }
}
// 后->前,找到比【Aj>Ai】的[j]位置
for(j=length-1; j>i; --j)
{
if(a[j]>a[i])
{ break; }
}
// 交换位置i,j的值
swap(int,a[i],a[j]);
// 【(i+1)至结束位置】的所有数据逆序
i++;
j=length-1;
for(; i<j; ++i,--j)
{
swap(int,a[i],a[j]);
}
}
}
void Permutation_Combination(int All,int Opt)
{
if(All<Opt || Opt<2) { return; }
// 组合算法
int flag=0;
int *com=new int[Opt+1];
com[0]=1;
while(1)
{
if(com[flag] > (All-Opt+flag+1))
{
if(flag == 0)
{
delete []com;
return;
}
com[--flag]++;
}
else
{
if(flag == (Opt-1))
{
// 得到一个组合,是升序排列
// 进而求出该组合的全排列
int *per=new int[Opt];
for(int i=0;i<Opt;i++)
{
per[i]=com[i];
}
Permutation(per,Opt);
cout<<"------------"<<endl;
delete []per;
}
com[flag+1]=com[flag++]+1;
if(flag == Opt) { com[--flag]++; }
}
}
}
/*----------------------------------------------------------
非递归组合算法
说明:
以5选3为例,共10种组合,如下:
... 百--十--个 位的数据
... 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,
1.可以看出百位的数据<=3,十位的数据<=4,个位的数据<=5,
即每个位置上的值都有各自的范围。
2.组合中的数据总是升序的,因为数据都是由高位推出低位。
3.采用进位的思路,低位数据超出范围,高1位进位。
4.定义:个位称为最低位。
---------------------------------------------------------*/
void Combination(int All,int Opt)
{
int i;
int flag=0; // 当前位置标识
int *com=new int[Opt+1]; // 要求数组长度>=(Opt+1)
com[0]=1; // 初始化最高位
while(1)
{
// 当前位置的值溢出
if(com[flag] > (All-Opt+flag+1))
{
if(flag == 0)
{
delete []com;
return; // 最高位溢出则结束。
}
// 低位溢出,高1位进位。
com[--flag]++;
}
// 当前位置的值没有溢出
else
{
if(flag == (Opt-1))
{
// 位置标识指向个位时,得到一个组合,输出
for(i=0;i<Opt;i++)
{ cout<<com[i]<<' '; }
cout<<endl;
cin.get();
}
// 低位=高位+1
com[flag+1]=com[flag++]+1;
// 个位的低1位称为最最低位
// 位置标识指向最最低位时,个位上的数进位
if(flag == Opt) { com[--flag]++; }
}
}
}
- 排列组合算法(非递归)
- 排列组合非递归算法的实现
- 排列组合递归和非递归算法总结篇
- 排列组合的递归算法
- c#排列组合递归算法
- 排列组合递归算法 java
- 排列组合算法(递归)1
- 排列组合算法-----使用递归
- 排列组合算法的递归实现
- 非递归枚举排列组合(C++)
- 非递归枚举排列组合(C++)
- 祝福:新春新年大吉大利。问鼎天下,谁与争锋。非递归非交换非转数组非无序全排列组合算法,诚邀比、测、评。
- java递归算法中的排列组合问题及排列组合去重
- 【算法】递归求解几类排列组合问题
- 排列组合算法之三: 递归法
- 字符串排列组合问题&递归算法(1)
- 字符串排列组合问题&递归算法(2)
- 递归算法转非递归
- arm权威指南及我们组项目笔记
- CSS优先级
- Kinect for Windows SDK开发入门(十八):Kinect Interaction交互控件
- WINCE6.0远程桌面显示修改
- C99中变长数组的内存分配策略
- 排列组合算法(非递归)
- (C语言)二叉树非递归遍历前序和中序(数据结构十四)
- 人搜笔试编程题——树的层序遍历
- 类的方法与属性(day05-13.10.17)
- Hibernate注解关系映射
- 全国省市数据库
- android使用ffmpeg的实例程序
- 程序 人生 历程
- C++文件操作写入和读取结构体类型