日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

出栈顺序 与 卡特兰数(Catalan)的关系

發(fā)布時(shí)間:2023/12/18 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 出栈顺序 与 卡特兰数(Catalan)的关系 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一,問(wèn)題描述

給定一個(gè)以字符串形式表示的入棧序列,請(qǐng)求出一共有多少種可能的出棧順序?如何輸出所有可能的出棧序列?

比如入棧序列為:1 2 3? ,則出棧序列一共有五種,分別如下:1 2 3、1 3 2、2 1 3、2 3 1、3 2 1

?

二,問(wèn)題分析

先介紹幾個(gè)規(guī)律:

對(duì)于出棧序列中的每一個(gè)數(shù)字,在它后面的、比它小的所有數(shù)字,一定是按遞減順序排列的。

比如入棧順序?yàn)?#xff1a;1 2 3 4。

出棧順序:4 3 2 1是合法的,對(duì)于數(shù)字 4 而言,比它小的后面的數(shù)字是:3 2 1,且這個(gè)順序是遞減順序。同樣地,對(duì)于數(shù)字 3 而言,比它小的后面的數(shù)字是: 2 1,且這個(gè)順序是遞減的。....

出棧順序:1 2 3 4 也是合法的,對(duì)于數(shù)字 1 而言,它后面沒(méi)有比它更小的數(shù)字。同樣地,對(duì)于數(shù)字 2 而言,它后面也沒(méi)有比它更小的數(shù)字。

出棧順序:3 2 4 1 也是合法的,對(duì)于數(shù)字 3 而言,它后面比 3 小的數(shù)字有: 2 1,這個(gè)順序是遞減的;對(duì)于數(shù)字 2 而言,它后面的比它 小的數(shù)字只有 1,也算符合遞減順序;對(duì)于數(shù)字 4 而言,它后面的比它小的數(shù)字也只有1,因此也符合遞減順序。

出棧順序:3 1 4 2 是不合法的,因?yàn)閷?duì)于數(shù)字 3 而言,在3后面的比3小的數(shù)字有:1 2,這個(gè)順序是一個(gè)遞增的順序(1-->2)。

?

因此,當(dāng)給定一個(gè)序列時(shí),通過(guò)這個(gè)規(guī)律 可以輕松地判斷 哪些序列是合法的,哪些序列是非法的。

?

②給定一個(gè)入棧順序:1? 2? 3 .... n,一共有多少種合法的出棧順序?參考:百度百科卡特蘭數(shù)

答案是 卡特蘭數(shù)。即一共有:h(n)=c(2n,n)/(n+1) 種合法的出棧順序。

如果僅僅只需要求出一共有多少種合法的出棧順序,其實(shí)就是求出組合 C(2n,n)就可以了。而求解C(2n,n),則可以用動(dòng)態(tài)規(guī)劃來(lái)求解,具體可參考: 排列與組合的一些定理

?

三,代碼實(shí)現(xiàn)

給定一個(gè)入棧順序,比如 1 2 3 ,如何輸出所有可能的出棧順序?

思路①:先求出入棧順序的所有排列(即全排列),并將排列保存到一個(gè)LinkedList<String>中,然后依次遍歷每一個(gè)序列,判斷該序列是否是合法的序列。

所謂合法的序列,就是滿足上面的規(guī)律1:對(duì)于出棧序列中的每一個(gè)數(shù)字,在它后面的、比它小的所有數(shù)字,一定是按遞減順序排列的。 關(guān)于如何求解一個(gè)序列的全排列,可參考:JAVA求解全排列?

完整代碼實(shí)現(xiàn)如下:(實(shí)現(xiàn)得不好,感覺(jué)比較復(fù)雜)

import java.util.Collections; import java.util.Iterator; import java.util.LinkedList;public class AllStackPopOrder {public static LinkedList<String> allPermutation(String str){if(str == null || str.length() == 0)return null;//保存所有的全排列LinkedList<String> listStr = new LinkedList<String>();allPermutation(str.toCharArray(), listStr, 0);//print(listStr);//打印全排列return listStr;}private static void allPermutation(char[] c, LinkedList<String> listStr, int start){if(start == c.length-1)listStr.add(String.valueOf(c));else{for(int i = start; i <= c.length-1; i++){//只有當(dāng)沒(méi)有重疊的字符 才交換if(!isSwap(c, start, i)){swap(c, i, start);//相當(dāng)于: 固定第 i 個(gè)字符allPermutation(c, listStr, start+1);//求出這種情形下的所有排列swap(c, start, i);//復(fù)位 }}}}private static void swap(char[] c, int i, int j){char tmp;tmp = c[i];c[i] = c[j];c[j] = tmp;}private static void print(LinkedList<String> listStr){Collections.sort(listStr);//使字符串按照'字典順序'輸出for (String str : listStr) {System.out.println(str);}System.out.println("size:" + listStr.size());}//[start,end) 中是否有與 c[end] 相同的字符private static boolean isSwap(char[] c, int start, int end){for(int i = start; i < end; i++){if(c[i] == c[end])return true;}return false;}public static LinkedList<String> legalSequence(LinkedList<String> listStr){Iterator<String> it = listStr.iterator();String currentStr;while(it.hasNext())//檢查全排列中的每個(gè)序列 {currentStr = it.next();if(!check(currentStr))it.remove();//刪除不符合的出棧規(guī)律的序列 }return listStr;}//檢查出棧序列 str 是否 是合法的出棧 序列private static boolean check(String str){boolean result = true;char[] c = str.toCharArray();char first;//當(dāng)前數(shù)字.int k = 0;//記錄 compare 數(shù)組中的元素個(gè)數(shù)char[] compare = new char[str.length()];for(int i = 0; i < c.length; i++){first = c[i];//找出在 first 之后的,并且比 first 小的數(shù)字for(int j = i+1; j < c.length; j++){if(c[j] > first)continue;else{compare[k++] = c[j];//將比當(dāng)前數(shù)字小的 所有數(shù)字 放在compare數(shù)組中 }}if(k == 0)continue;else{for(int m = 0; m < k-1; m++)//判斷 compare 數(shù)組是否是 遞減的順序 {if(compare[m] < compare[m+1]){result = false;//不符合遞減順序return result;}}}k=0;}return result;}//hapjin testpublic static void main(String[] args) {String str = "1234";LinkedList<String> listStr = legalSequence(allPermutation(str));print(listStr);} } View Code

?

思路②:直接求出合法的出棧序列。【而不是像思路①那樣:先求出所有可能的出棧序列(求全排列),然后再找出合法的出棧序列。】

待完成。

?

四,參考資料

JAVA求解全排列

出棧順序(卡特蘭數(shù))

可能的出棧順序

轉(zhuǎn)載于:https://www.cnblogs.com/hapjin/p/5758083.html

總結(jié)

以上是生活随笔為你收集整理的出栈顺序 与 卡特兰数(Catalan)的关系的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。