Input will consist of multiple problem instances. Each instance will consist of a line of the form m s1 s2, indicating that the trees are m-ary trees, s1 is the pre-order traversal and s2 is the post-order traversal.All traversal strings will consist of lowercase alphabetic characters. For all input instances, 1 <= m <= 20 and the length of s1 and s2 will be between 1 and 26 inclusive. If the length of s1 is k (which is the same as the length of s2, of course), the first k letters of the alphabet will be used in the strings. An input line of 0 will terminate the input.
For each problem instance, you should output one line containing the number of possible trees which would result in the pre-order and post-order traversals for the instance. All output values will be within the range of a 32-bit signed integer. For each problem instance, you are guaranteed that there is at least one tree with the given pre-order and post-order traversals.
2 abc cba 2 abc bca 10 abc bca 13 abejkcfghid jkebfghicda
4 1 45 207352860
import java.util.*; class SubTree{ public SubTree(String pre,String post){ this.pre = pre; this.post = post; } String pre; String post; } public class Main{ //计算阶乘 public static long fac(int n){ long f = 1; for(int i = 1;i <= n;i++){ f *= i; } return f; } //计算C n m public static long calcCom(int n,int m){ m = m < (n - m)? m : (n - m); long r = 1; for(int i = n;i >= n - m + 1;i--){ r *= i; } return r / fac(m); } public static List<SubTree> calcSubTree(String prev,String post){ //子树的根在前序遍历结果中的位置 int subRootPreIdx = 1; //后序遍历 int postFirst = 0; List<SubTree> subTreeList = new ArrayList<>(); while(subRootPreIdx < prev.length()){ //确认该棵子树的根节点 char rootSub = prev.charAt(subRootPreIdx); int subRootPostIdx = post.indexOf(rootSub); int subTreeNodeCount = subRootPostIdx - postFirst + 1; //从前序和后续遍历结果中分离出该棵子树的前序和后序遍历结果 SubTree subTree = new SubTree( prev.substring(subRootPreIdx,subRootPreIdx + subTreeNodeCount), post.substring(postFirst,postFirst + subTreeNodeCount) ); subTreeList.add(subTree); //继续分离下一棵子树 subRootPreIdx += subTreeNodeCount; postFirst += subTreeNodeCount; } return subTreeList; } public static long CalcTreePossible(int m,String pre,String post){ if(pre.isEmpty() || pre.length() == 1){ return 1; } //先分离出根节点有多少棵树 List<SubTree> subTree = calcSubTree(pre,post); //根节点子树可能性的组合结果 long result = calcCom(m,subTree.size()); //根的子树有多少种可能性 for(SubTree e : subTree){ result *= CalcTreePossible(m,e.pre,e.post); } return result; } public static void main(String[] args){ Scanner in = new Scanner(System.in); while (in.hasNext()) { int m = in.nextInt(); if(m == 0){ break; } //接收子树的前序和后续遍历结果 String pre = in.next(); String post = in.next(); System.out.println(CalcTreePossible(m,pre,post)); } } }