2種の文字A,Bの順列について考える 同一文字の1つづきを1つの連という
例えばAABABB ではAA,B,A,BBの4個の連を持つ
A,Bを5個ずつ計10個を1列に並べるときの連の個数の期待値を求めよ
※参考URL
http://okwave.jp/qa/q8808555.html
{連の個数}=({文字の変わり目}+1)[個]で計算しました。(^_^;
連の個数の最大値は10、最小値は2で、1の分は不要ですが、1の分も含めて、連の個数が1〜10になる場合の数をそれぞれカウントした結果も表示するようにしました。
ちなみに、計算式を書くと次の通りです。(^_^;
● ExpectedValue1.java
/* * ExpectedValue1.java * */ public class ExpectedValue1 { // 順列生成 static boolean nextPerm(char[] p, int n, int r) { int i, j; char t; if(r <= 0 || n < r) return(false); for(i = r + 1; i <= n-1; i++) for(j = i; j >= r + 1 && p[j-1] < p[j]; j--){ t = p[j]; p[j] = p[j-1]; p[j-1] = t; // swap(p,j,j-1); } for(i = n - 1; i > 0 && p[i-1] >= p[i]; i--); if(i==0) return(false); for(j = n - 1; j > i && p[i-1] >= p[j]; j--); t = p[j]; p[j] = p[i-1]; p[i-1] = t; // swap(p,j,i-1); for(j = n - 1; i < j; i++, j--){ t = p[i]; p[i] = p[j]; p[j] = t; // swap(p,i,j); } return(true); } static int gcd(int a, int b){ return( b == 0 ? a : gcd(b, a % b) ); } static int countRen(char[] c){ int count = 1; for(int i=0; i< c.length-1; i++) if(c[i]!=c[i+1]) count++; return count; } public static void main(String[] args) { final String P = "AAAAABBBBB"; final int N = P.length(); char[] p = P.toCharArray(); // 順列生成用 int total = 0, g=1; int[] count = new int[10]; long tm=System.nanoTime(); // Timer Start do{ total++; count[countRen(p)-1]++; }while(nextPerm(p,N,N)); int numerator = 0; for(int i=0; i< count.length; i++){ numerator += (i+1)*count[i]; System.out.printf("%2d:%3d\n",i+1,count[i]); } if(numerator!=0) g=gcd(numerator, total); System.out.printf("∴%d / %d = %d / %d\n",numerator,total,numerator/g,total/g); tm=System.nanoTime()-tm; // Timer Stop System.out.printf("Runtime : %.3f [sec]\n",(double)tm/1e9); } }
●実行結果
1: 0 2: 2 3: 8 4: 32 5: 48 6: 72 7: 48 8: 32 9: 8 10: 2 ∴1512 / 252 = 6 / 1 Runtime : 0.025 [sec]