n个互异字符串的全排列

        本节讨论通过递归调用实现互异字符串的全排列。

        考虑两个字符的全排列为两者交换顺序;三个字符的全排列则可以用抽取一个交换到第一个位置,剩下的两个字符仿照两个字符的情况实现全排列;以此类推,当n个字符全排列,先抽取一个 交换到第一个位置,剩下的n-1个字符实现全排列,此时则是递归调用的形式。

        下面为p位置到q位置的全排列示意图:

        

 先编写交换函数swap()

// 交换位置
void swap(char a[], int p, int q) {
    char temp = a[p];
    a[p] = a[q];
    a[q] = temp;
}

 由于过程中需要打印出字符数组的元素,故需要编写打印函数printArray()

// 打印数组
void printArray(char a[],int n){
    for(int i=0; i<n; i++) 
        cout<<a[i];
}

整合以上可编写全排列函数perm()

// 全排列
void perm(char a[],int p,int q) {
    if (p == q) {
        printArray(a,q+1);
        cout<<endl;
    }else {
        int i;
        for(i=p; i<=q; i++) {
            swap(a,p,i);
            perm(a,p+1,q);
            swap(a,p,i);
        }
    }
}

注意到要求字符串互异,为增强程序的鲁棒性,可编写判定互异的函数difference()

// 判断互异
bool diffenerce(char a[],int n){
     for(int i=0; i<n; i++) {
        for(int j=i+1; j<n; j++) {
            if(a[i]==a[j]){
                cout<<"请重新输入不同的字符:"<<endl;
                return false;
            }
        }
    }
    return true;
}

mian.cpp

int main() {
    cout<< "请输入字符数n:" <<endl;
    int n;
    cin>>n;
    cout<< "请输入n个不同的字符:" <<endl;
    char *a = (char*)malloc(sizeof(char)*n);
    bool flag;
    do{
        for(int i=0; i<n; i++) {
            cin>>a[i];
        }
        flag = diffenerce(a,n);
    }while(!flag);
    cout<< "以上n个不同字符的全排列为:" <<endl;
    perm(a,0,n-1);
    free(a);
    return 0;
}

全部程序如下:

#include <iostream>

using namespace std;

// 交换位置
void swap(char a[], int p, int q) {
    char temp = a[p];
    a[p] = a[q];
    a[q] = temp;
}

// 打印数组
void printArray(char a[],int n){
    for(int i=0; i<n; i++) 
        cout<<a[i];
}
// 全排列
void perm(char a[],int p,int q) {
    if (p == q) {
        printArray(a,q+1);
        cout<<endl;
    }else {
        int i;
        for(i=p; i<=q; i++) {
            swap(a,p,i);
            perm(a,p+1,q);
            swap(a,p,i);
        }
    }
}
// 判断互异
bool diffenerce(char a[],int n){
     for(int i=0; i<n; i++) {
        for(int j=i+1; j<n; j++) {
            if(a[i]==a[j]){
                cout<<"请重新输入不同的字符:"<<endl;
                return false;
            }
        }
    }
    return true;
}

int main() {
    cout<< "请输入字符数n:" <<endl;
    int n;
    cin>>n;
    cout<< "请输入n个不同的字符:" <<endl;
    char *a = (char*)malloc(sizeof(char)*n);    //为字符数组分配内存空间
    bool flag;
    do{
        for(int i=0; i<n; i++) {
            cin>>a[i];
        }
        flag = diffenerce(a,n);
    }while(!flag);
    cout<< "以上n个不同字符的全排列为:" <<endl;
    perm(a,0,n-1);
    free(a);    //释放空间
    return 0;
}