进入大学后每天似乎都在努力学习,但是感觉总是学不会什么东西。昨天在健身房跟同学聊天,提到学了东西之后可以自己写一些东西来巩固记忆和理解。今天刚刚接触到一个关于数组递归全排列的问题,看了别人写的相关介绍,自己根据理解也来献丑一下。
我这里写的数组全排列问题主要用的就是递归的方法来实现这个数组的全排列问题。
array[4]={1,2,3,4},对这个数组进行全排列。主要思路是:
1.将这个全排列理解为往四个xxxx中填充数字问题,第一个x处有四种选择,第二个x处有三个选择,第三个x处有两个选择,第四个x处只有一种选择。这样就将这个问题分解为几个性质相同的小问题,可以采用递归的方法来解决。
2.将上面的思路用编程的思想来考虑。
由上面分析可得,首先将问题分解为四个小问题,然后第二步中将第一步中的每个小问题分解为三个小问题,第三步将第二步中的每个子问题又分解为两个问题。其中每个子问题的性质都是与原问题相似的,先是四个数的全排列,然后是三个数的全排列,然后是两个数的排列,最后将最后一个数放在最后的位置。所以是一个递归问题,需要完成的事情相同,只是数目不同而已,所以对应到函数就是功能相同,参数不同。
// 数组的全排列问题.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
int sum = 0;
void print(int array[], int len)
{
for (int i = 0; i < len; i++)
{
cout << array[i];
}
cout << endl;
}
void swap(int array[], int a, int b)
{
int temp = array[a];
array[a] = array[b];
array[b] = temp;
}
void permuta(int array[], int len, int index)
{
if (index==len)
{
print(array, len);
sum++;
}
for (int i = index; i < len; i++)
{
//交换两个数
swap(array, i, index);
permuta(array, len, index + 1);
//将两个数还原,以便i++后与index交换时符合程序的设计思路
swap(array, i, index);
}
}
int main()
{
int array[4] = { 1,2,3,4};
permuta(array, 4, 0);
cout << sum;
return 0;
}
输出sum为24。
程序的运行思路是先沿着一个问题递归求得下面所有的子问题,然后通过for循环求解与其平行的其他子问题。
例如,对于序列4,2,3,1。它有三个子问题,4,2,3,1 4,3,2,1 4,1,3,2,对于最后一个序列4,1,3,2,有两个子问题,4,1,3,2 4,1,2,3。这两个问题已经不能分解,此时的index==len,打印出序列。
这是一个递归到底的过程,然后接下来程序会求解与4,1,3,2平行的两个序列4,2,3,1 4,3,2,1,求解完成后再返回求解与4,2,3,1平行的三个子问题。
总结:写的有些不知所云,纯粹出于为了增加自己的记忆和理解,每个人的想法可能不一样。个人认为这个问题中最重要的就是理解for循环和递归的运行过程,结合在数学层面上对全排列的理解就会很容易明白。