全排列 字典序排列

智商是個好東西,自己寫了一下午沒寫出來,最後還得靠劍指offer書上的思路

上劍指

這裏寫圖片描述
這裏寫圖片描述

根據以上的思路寫出的代碼

#include<iostream>  
using namespace std;  

int counter=0;

void permutation(char * str,char *begin)
{
        if(*begin == '\0')
        {
                cout<<counter<<":"<<str<<endl;
                counter++;
        }
        else
        {
                for(char *p = begin;*p!='\0';p++)
                {
                        if(p!=begin && *p == *begin)
                                continue;   //去掉重複的 比如 aa 和 aa

                        char tmp=*p;
                        *p = *begin;
                        *begin = tmp;

                        permutation(str,begin+1);

                        /*原書上的代碼 我去掉好像也沒事 可能我沒有遇到某些特殊情況吧*/
                        tmp = *p;
                        *p = *begin;
                        *begin = tmp;
                        /****************************/
                }
        }
}


int main()
{   
    char str[] ={'a','b','c','\0'};  

    permutation(str,str);  
    return 0;  
}  

字典排序

 一般而言,設P是[1,n]的一個全排列。
 P=P1P2…Pn=P1P2…Pj-1PjPj+1…Pk-1PkPk+1…Pn
find:  j=max{i|Pi<Pi+1}
    k=max{i|Pi>Pj}
1,  對換Pj,Pk,
2,  將Pj+1…Pk-1PjPk+1…Pn翻轉
       P’= P1P2…Pj-1PkPn…Pk+1PjPk-1…Pj+1即P的下一個


 如何得到346987521的下一個
    1,從尾部往前找第一個P(i-1) < P(i)的位置
            3 4 6 <- 9 <- 8 <- 7 <- 5 <- 2 <- 1
        最終找到6是第一個變小的數字,記錄下6的位置i-1
    2,從i位置往後找到最後一個大於6的數
            3 4 6 -> 9 -> 8 -> 7 5 2 1
        最終找到7的位置,記錄位置爲m
    3,交換位置i-1和m的值
            3 4 7 9 8 6 5 2 1
    4,倒序i位置後的所有數據
            3 4 7 1 2 5 6 8 9347125689346987521的下一個排列

寫出代碼  由於太懶  翻轉部分直接冒泡重排了
void setmin(char *str,int length,const int protect)
{
        int i=0,j=0;
        //冒泡獻醜
        for(i=protect;i<length;i++)
                for(j=i;j<length;j++)
                {
                        if(str[i]>str[j])
                        {
                                char tmp = str[i];
                                str[i] = str[j];
                                str[j] = tmp;
                        }
                }
}

int setnext(char *str,int length)
{
        for(int i=length-1;i>0;i--)
        {
                if(str[i]>str[i-1])
                {
                        for(int j=length-1;j>=i;j--)
                        {
                                if(str[j]>str[i-1])
                                {
                                char tmp = str[j];
                                str[j]=str[i-1];
                                str[i-1] = tmp;
                                setmin(str,length,i);
                                return 1;
                                }
                        }
                        return 0;
                }
        }
        return 0;
}

int main()
{   
    char str[] ={'b','a','c','d','\0'};  

    setmin(str,4,0);

        printf("%s\n",str);
        while(setnext(str,4))
                printf("%s\n",str);
    return 0;  
} 
發佈了52 篇原創文章 · 獲贊 7 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章