Counting Sheep_SAFIA

这篇博客探讨了如何处理含有重复元素的排列问题,介绍了两种方法:普通算法和回溯法。普通算法通过递归实现全排列,避免重复排列,而回溯法则通过交换和递归实现所有可能的排列。文章还提供了C++代码示例,并讲解了bool类型的使用。此外,博主分享了关于字符数组和内存管理的知识。
摘要由CSDN通过智能技术生成

有重复元素的排列问题

Title:如题,就是有重复元素的排列问题,就是不一定是数组。

有两种方案,一种是普通方法,一种是回溯法。

首先是普通算法。

其实就是一层层函数套出来,划分为n个,n-1个,n-2个.......这样的全排列。每一个元素都有作为第一个元素的机会,然后交换递归,周而复始。

代码:

#include<bits/stdc++.h>
using namespace std;
int c=0;
void swap(char &a,char &b)
{
    char temp;
    temp=a;
    a=b;
    b=temp;
}
int List(char list[],int k,int i)
{
    if(i>k)
    {
        for(int j=k;j<i;j++)
            if(list[j]==list[i])
                return 0;    
    }
    return 1;
}
/*List函数是判断准备与当前位置的字符交换的字符, 
是不是已经出现过,如果已经出现过,
该字符已经在当前位置摆放过了,就不需要再摆一次了。
例如,abccccc,a只要和第一个c交换过,
就不需要再和后面的c交换了*/ 
void sc(char list[],int k,int m)
//sc里的k也是传入的参数,是待排列的起始下标
//i是sc中的循环变量,是待与list[k]交换的字符的下标。 
{
    if(k==m)     
    {
        c++;
        for(int i=0;i<=m;i++)
        cout<<list[i];
        cout<<endl; 
    }
    for(int i=k;i<=m;i++)  
    {
            if(List(list,k,i))//检查 list[k]~list[i-1] 中有没有和 list[i]一样的字符。 
        {
            swap(list[k],list[i]);
            sc(list,k+1,m);//对list[k+1]~list[m]进行全排列 
            /*步骤是:依次把list[k]~list[m]换到左边的list[k],
            再对剩下的list[k+1]~list[m]进行全排列,
            list[k+1]~list[m]全排列完再把刚才换到list[k]的字符换回原位。*/ 
            swap(list[k],list[i]);
        }
    }        
}
/*sc是输出函数, 
int main()
{
    int i,n;
    cin>>n;
    getchar();
    char *a=new char[n];//用来读输入的字符 
    for(i=0;i<n;i++)
        cin>>a[i];
    sc(a,0,n-1);//main是第一个调用sc的,sc(list, 0, n-1)表示要sc对整个list进行全排列
    cout<<c;
    return 0;

知识储备:

1'

char *a = "12345"; // 字符串常量, 更推荐写const char*

char b[] = "12345"; // 栈区开辟空间, 动态

char *c = new char[6]; // 堆区开辟空间, 动态

strcpy(c, "12345");

delete []c;

2.

3.

C++中的bool类型。其实是跟int、char什么的是一样的,但bool是规定只有两种可能,true 和 false

不像是return,return0就是非,return一个非零就是true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值