排列组合的算法

举个例子:

问题是这样的:
假如有4组数据,每组数据都是{1,2,3,4},组成一个矩阵,即:
{
{1,2,3,4},
{1,2,3,4},
{1,2,3,4},
{1,2,3,4},
}从每组数据中取出一个,组合成一个新的数据,
那我怎么样得到所有的新数据呢?
----------------------------------------------------------------------------------------------

简单的for循环,效率不高

#include <iostream>
using namespace std;

int main()
{
int x[4][4]=
{
{1,2,3,4},
{5,6,7,8},
{1,2,3,4},
{1,2,3,4},
};
for(int a=0; a<4; ++a)
for(int b=0; b<4; ++b)
for(int c=0; c<4; ++c)
for(int d=0; d<4; ++d)
cout<<"{"<<x[0][a]<<x[1][b]<<x[2][c]<<x[3][d]<<"}"<<endl;
return 0;
}

----------------------------------------------------------------------------------------------------

#include <iostream>
using namespace std;

const int count=3;
int a[count][count];
int p[count];
int n;

void f()
{
int i;
if (n<0)
{
return;
}
for (int i=0; i<count; i++)
{
cout << a[i][p[i]];
}
cout <<endl;

p[n]++;
if (p[n]>=count)
while (p[n]>=count)
{
p[n]=0;
n--;
p[n]++;
if (n<0)
{
return;
}
}
n = count-1;
f();
}

main()
{
for (int i=0; i<count; i++)
for (int j=0; j<count; j++)
a[i][j] = j+1;
n = count-1;
f();
}

-------------------------------------------------------------------------------------------------------------------

看看更泛化些的,在每次循环里,你想做什么都行,只要你给个合适的函数指针。

#include <IOSTREAM>
#include <VECTOR>

using namespace std;

typedef
unsigned int
Counter;
typedef
vector<Counter>
CounterArrayType;
typedef
void (*DoThing)(CounterArrayType &);

Counter P(Counter Depth, const CounterArrayType & Endians, DoThing ThingToDo);

void ATestThing(CounterArrayType &);

int main(int argc, char* argv[])
{
int n = 3;
CounterArrayType Endian(size_t(n), 4);
cout << P(n, Endian, ATestThing);
cin >> n;
return 0;
}

Counter P(Counter Depth, const CounterArrayType & Endians, DoThing ThingToDo) {
Counter atDepth = 0, runTimes = 0;
bool Finished = false;
vector<Counter> LoopVar( Depth, 0 );
while (!Finished) {
atDepth = 0;
(*ThingToDo)(LoopVar);
++runTimes;
while (++LoopVar[atDepth] == Endians[atDepth]) {
LoopVar[atDepth++] = 0;
if (atDepth == Depth) {
Finished = true;
break;
}
}
}
return runTimes;
}

void ATestThing(CounterArrayType & vTest) {
static CounterArrayType::iterator itvTest;
cout << '[' << vTest.size() << ']';
for(itvTest = vTest.begin(); itvTest != vTest.end(); ++itvTest )
cout << ' ' << *itvTest;
cout << endl;
}
简单说说思路:

对于某次特定的循环,若把它的各层循环变量连接起来,可以得到一个数字序列。
对于不定循环次数的情况,该序列可以理解为一个“各位进位制不一定相等”的数字。
这样,在该数字从 0 到 MAX - 1 的过程中,就遍历了所有的循环情况。

Counter P(Counter Depth, const CounterArrayType & Endians, DoThing ThingToDo)
该函数返回值是循环进行的次数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值