排列组合/八皇后问题

全排列的递归解法法一

#include <iostream>
#include <cstdio>

using namespace std;

void swap_alpha(char *a,char *b)
{
    char temp=*a;
    *a=*b;
    *b=temp;
    return;
}



void main_function(char *str,char *pbegin)
{
    if(*pbegin=='\0')
    {
        printf("%s\n",str);   //注意str和pbegin指向同一块内存
        return;
    }

    for(char *ch=pbegin;*ch!='\0';ch++)
    {
        swap_alpha(ch,pbegin);
        main_function(str,pbegin+1);
        swap_alpha(pbegin,ch);   //排列完之后再交换回来字符
    }
    return;
}

void full_permutation(char *str)
{
    if(str==NULL)
        return;
    char *pbegin=str;
    main_function(str,pbegin);
    return;
}

int main()
{
    char str[]="abcd";
    full_permutation(str);
    return 0;
}

全排列的递归解法法二

#include <iostream>
#include <cstdio>
#include <cstring>

//using namespace std;
void swap_alpha(char *a,char *b)
{
    char temp=*a;
    *a=*b;
    *b=temp;
    return;
}


void full_permutation(int k,int m,char *str)
{
    if(str==NULL)
        return;

    if(k==m)
    {
        printf("%s\n",str);
        return;
    }

    for(int i=k;i<=m;i++)
    {
        swap_alpha((str+k),(str+i));
        full_permutation(k+1,m,str);
        swap_alpha((str+k),(str+i));
    }

    return;

}

int main()
{
    char str[]="abcd";
    full_permutation(0,strlen(str)-1,str);
    return 0;
}

去重的全排列递归解法(上述2中不可以实现自动去重)

#include <iostream>
#include <cstdio>

void swap_alpha(char *a,char *b)
{
    char temp=*a;
    *a=*b;
    *b=temp;
    return;
}

bool isswap(char *start_,char *end_)
{
    for(char *index=start_;index!=end_;index++)
    {
        if(*index==*end_)
            return false;
    }
    return true;
}

void full_permutation(char *str,char *pbegin)
{
    if(str==NULL)
        return;
    if(*pbegin=='\0')
    {
        printf("%s\n",str);
        return;
    }

    for(char *ch=pbegin;*ch!='\0';ch++)
    {
        if(isswap(pbegin,ch))  //判断[pbegin,ch)区间是不是有字符与ch所指字符重复
        {
            swap_alpha(ch,pbegin);
            full_permutation(str,pbegin+1);
            swap_alpha(ch,pbegin);
        }

    }
    return;
}

int main()
{
    char str[]="acc";
    full_permutation(str,str);
    return 0;
}

全排列的非递归解法(自动去重)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

void swap_alpha(char *a,char *b)
{
    char temp=*a;
    *a=*b;
    *b=temp;
    return;
}

void reverse_str(char *begin_,char *end_)
{
    char *front_=begin_;
    char *back_=end_;
    while(front_<back_)
    {
        swap_alpha(front_,back_);
        front_++;
        back_--;
    }
}

int cmp(const void *a,const void *b)
{
    return int(*(char *)a-*(char *)b);
}

bool next_permutation_my(char *str)
{
    char *p=str;
    p=p+strlen(str)-1;
    char *last=p;
    char *q=p;
    while(q!=str)
    {
        q--;
        if(*q<*p)
        {
            char *pfind=last;
            while(*pfind<*q)
            {
                pfind--;
            }
            swap_alpha(pfind,q);
            reverse_str(q+1,last);
            return true;
        }
        p=q;
    }
    return false;
}

int main()
{
    char str[]="acc";
    qsort(str,strlen(str),sizeof(char),cmp);
    int num=1;
    do
    {
        printf("第%d个排列为: ",num++);
        printf("%s\n",str);
    }
    while(next_permutation_my(str));
    return 0;
}

组合法一

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>

using namespace std;

static int index=1;

void combination_core(char *str,int number,vector<char> &result)
{
    if(number==0)
    {
        printf("第%d个组合为:",index++);
        for(vector<char>::iterator it=result.begin();it!=result.end();it++)
        {
            printf("%c",*it);
        }
        printf("\n");
        return;
    }

    if(*str=='\0')
        return;
    result.push_back(*str);
    combination_core(str+1,number-1,result);
    result.pop_back();
    combination_core(str+1,number,result);
}

void combination(char *str)
{
    if(str==NULL)
        return;
    vector<char> result;
    int length=strlen(str);
    for(int i=1;i<=length;i++)
    {
        combination_core(str,i,result);
    }
}

int main()
{
    char str[]="abcde";
    static int index=1;
    combination(str);
    return 0;
}

组合法二(位运算)

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

static int index=1;

void combination(char *str,int s)
{
    int length=strlen(str);
    printf("第%d个组合为: ",index++);
    for(int i=0;i<length;i++)
    {
        if(s&(1<<i))
            printf("%c",str[i]);
    }
    printf("\n");
}

int main()
{
    char str[]="abcd";
    int length=strlen(str);
    for(int i=1;i<(1<<length);i++)   //[1,(1<<length))的二进制表示刚好可以把所有的组合都包括了。(二进制表示中0表示未选
    //相应下标位置的字符,反之选择了相应位置的下标)
    {
        combination(str,i);
    }

    return 0;
}

八皇后问题

#include <iostream>
#include <cstdio>

using namespace std;
static int index=1;

void swap_int(int *a,int *b)
{
    int temp=*a;
    *a=*b;
    *b=temp;
}

bool is_satisfy(int a[])
{
    for(int i=0;i<8;i++)
    {
        for(int j=i+1;j<8;j++)
        {
            if((i-j==a[i]-a[j])||(i-j==a[j]-a[i]))
                return false;
        }
    }
    return true;
}

void print(int a[])
{
    for(int i=0;i<8;i++)
    {
        printf("%d",a[i]);
    }
    printf("\n");
}

void permutation(int a[],int b[])
{
    if(b>(a+7))
    {
        if(is_satisfy(a))
        {
            printf("第%d个8皇后组合为:",index++);
            print(a);
            return;
        }
    }

    for(int *s=b;s<=a+7;s++)
    {
        swap_int(s,b);
        permutation(a,b+1);
        swap_int(s,b);
    }
    return;
}

int main()
{
    int a[8]={0,1,2,3,4,5,6,7};
    permutation(a,a);
    return 0;
}

过程链接见博客

猜你喜欢

转载自blog.csdn.net/qq_40123329/article/details/86763293