n个元素的全排列C语言,n个元素的全排列(递归+去重)
排列组合是算法常用的基本工具,如何在c语言中实现排列组合呢?思路如下:
本文主要探讨递归实现,由于递归将问题逐级分解,因此相对比较容易理解,但是需要消耗大量的栈空间,如果线程栈空间不够,那么就运行不下去了,而且函数调用开销也比较大。
(1) 全排列:
全排列表示把集合中元素的所有按照一定的顺序排列起来,使用P(n, n) = n!表示n个元素全排列的个数(假设集合中没有重复元素)。
例如:{1, 2, 3}的全排列为:
123;132;
213;231;
312;321;
共6个,即3! = 6。
这个是怎么算出来的呢?
首先取一个元素,例如取出了1,那么就还剩下{2, 3}。
然后再从剩下的集合中取出一个元素,例如取出2,那么还剩下{3}。
以此类推,把所有可能的情况取一遍,就是全排列了,如图:
小记:全排列就是从第一个数字起每个数分别与它后面的数字交换。
知道了这个过程,算法也就写出来了:
将数组看为一个集合,将集合分为两部分:0~k和k~m,其中0~k表示已经选出来的元素,而k~m表示还没有选择的元素。
AllRange(set, k, m)
{
顺序从k~m中选出一个元素与k交换(即选出一个元素)
调用AllRange(set, k + 1, m)
直到 k = m 时,输出set
}
小记:去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。用编程的话描述就是第i个数与第j个数交换时,要求[i,j)中没有与第j个数相等的数。有两种方法(1)可以每次在需要交换时进行顺序查找;(2)用哈希表来查重;下面使用方法(1)。
具体实现如下:
#include
using namespace std;
void Swap(char *a, char *b)
{
char temp = *a;
*a = *b;
*b = temp;
}
//在pStr数组中,[nBegin,nEnd)中是否有数字与下标为nEnd的数字相等
bool IsSwap(char *pStr, int nBegin, int nEnd)
{
for (int i = nBegin; i < nEnd; i++)
if (pStr[i] == pStr[nEnd])
return false;
return true;
}
// k表示当前选取到第几个数,m表示数组中共有多少数。(k,m对应的是数组中的下标)
void AllRange(char *pStr, int k, int m)
{
if (k == m)
{
cout << pStr << endl;
}
else
{
for (int i = k; i <= m; i++) // 第i个数分别与它后面的数字交换就能得到新的排列
{
if (IsSwap(pStr, k, i))
{
Swap(pStr + k, pStr + i);
AllRange(pStr, k + 1, m);
Swap(pStr + k, pStr + i);
}
}
}
}
void Permutation(char *pStr)
{
if (pStr == NULL)
return;
AllRange(pStr, 0, (int)strlen(pStr) - 1);
}
int main(int argc, const char * argv[]) {
char str[] = "121"; // 如果初始时,给出的是字符串形式。
Permutation(str);
return 0;
}
//int main(int argc, const char * argv[]) {
//
// int arr[] = {1,2,1}; // 如果初始时,给出的是整型数组,可先将整型数组转换为字符数组的形式。
// char str[3];
// int i;
// for (i = 0; i < 3; i++)
// {
// str[i] = arr[i] + '0'; // 将整型数组转换为字符串
// }
// str[i] = '\0'; // 字符串结束字符
//
// Permutation(str);
//
// return 0;
//}
n个元素的全排列C语言,n个元素的全排列(递归+去重)相关推荐
- 全排列:不含重复元素和含重复元素的全排列
1.不含重复元素 算法思路: 1.n个元素全排列 = (n-1)个元素的全排列+(另一个元素作为前缀) 2.出口:如果只有一个元素的全排列,则说明已经排完,输出数组: 3.不断将每个元素放在第一个元素 ...
- Xamarin XAML语言教程对象元素的声明方式
Xamarin XAML语言教程对象元素的声明方式 XAML的对象元素的声明有两种形式,分别为包含属性的特性语法形式以及对象元素语法形式.在1.4小节中,我们看到了其中一种对XAML对象元素的声明方式 ...
- Algorithm:C++语言实现之字符串相关算法(字符串的循环左移、字符串的全排列、带有同个字符的全排列、串匹配问题的BF算法和KMP算法)
Algorithm:C++语言实现之字符串相关算法(字符串的循环左移.字符串的全排列.带有同个字符的全排列.串匹配问题的BF算法和KMP算法) 目录 一.字符串的算法 1.字符串的循环左移 2.字符串 ...
- c语言打印数组元素_C程序打印元素差为0或1的子集数
c语言打印数组元素 Given an array of integers, find and print the maximum number of integers you can select f ...
- Problem B: C语言习题 矩阵元素变换
Problem B: C语言习题 矩阵元素变换 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 942 Solved: 558 [Submit][St ...
- 动态二维数组外圈元素值的和_C语言 | 用指向元素的指针变量输出二维数组元素的值...
例33:有一个3*4的二维数组,要求用C语言实现指向元素的指针变量输出二维数组个元素的值. 解题思路:二维数组的元素时整型的,它相当于整型变量,可以用int*型指针变量指向它.二维数组的元素在内存中是 ...
- c语言中的下标变量是什么,c语言引用数组元素时其数组下标的允许的数据类型是什么...
c语言引用数组元素时其数组下标的允许的数据类型是什么 发布时间:2020-07-30 11:56:52 来源:亿速云 阅读:621 作者:Leah c语言引用数组元素时其数组下标的允许的数据类型是什么 ...
- python电子章_python二级电子教案 第2章 Python语言基本语法元素
<python二级电子教案 第2章 Python语言基本语法元素>由会员分享,可在线阅读,更多相关<python二级电子教案 第2章 Python语言基本语法元素(46页珍藏版)&g ...
- C语言编程>第二十六周 ① 函数fun的功能是:将形参b所指数组中的前半部分元素的值和后半部分元素的值对换。形参n中存放数组中数据的个数,若n为奇数,则中间的元素不动。
例题:函数fun的功能是:将形参b所指数组中的前半部分元素的值和后半部分元素的值对换.形参n中存放数组中数据的个数,若n为奇数,则中间的元素不动. 例如,若a所指数组中的数据依次为:11 22 33 ...
最新文章
- tcpdump的使用
- windows搭建内网 域环境 域控制器 win7加入域
- OpenCV像素点处理 1
- why-use-getters-and-setters
- ffmpeg-URL(转)
- python pdf转txt保留全部信息_Python 将pdf转换成txt(不处理图片)
- python画画用哪库好_数据可视化哪款工具更好用?对比7款Python 数据图表工具的性能...
- mysql for update死锁_Mysql 数据库死锁过程分析(select for update)
- !DOCTYPE html 到底是什么意思?
- 十大经典算法_家庭用电预测:线性回归算法(时间与功率功率与电流之间的关系)
- 微信小游戏开发(11)-文件系统
- IEEE-SA董事刘东:开放+开源将带来新一波SDNFV创新
- 计算机cad标题栏快捷键,CAD标题快捷键
- 电阻电感电容基本单位、读数、封装类型、种类
- linux查看ftp默认端口,linux系统如何修改ftp默认端口(图文)
- python爬取加密qq空间_python+selenium+requests爬取qq空间相册时遇到的问题及解决思路...
- 二手闲鱼源码 php 如何搭建
- PS 2019 Mac版 自学入门系列(二)——区域选中
- 论文记录1_YOLO系列(v1 v2 v3 v4)
- 海润与联合“罗生门”升级