lff0305 最近的时间轴更新
lff0305

lff0305

V2EX 第 385776 号会员,加入于 2019-02-21 12:12:40 +08:00
lff0305 最近回复了
见过上海和国外的几个 bank,都是花钱买的 Redhat 的服务。PROD 就是 Redhat 企业版。Dev/Test 就是 CentOS
排版乱了, 重新弄下

简单写了个程序。题目没有讲太清楚(是否这些字母一定要全部使用)。这里为了简单就假设全部使用。

解法一:排列组合。生成字符串长度是 sum=a0+a1+a2+...+a25 。放 a,有(sum, a0)种选择的方法;放 b,有(sum - a0, a1)种方法;放 c,有(sum - a0 - a1, a2)种方法。。。。直到最后。

写出程序:
```
private long solve1(int[] letters) {
int sum = 0;
for (int c : letters) {
sum += c;
}
BigInteger r = BigInteger.ONE;
for (int c : letters) {
BigInteger s = choose(sum, c);
r = r.multiply(s);
sum -= c;
}
return r.longValue();
}

private static BigInteger choose(int n, int k) {
BigInteger r = BigInteger.ONE;
for (int i=0; i<k; i++) {
r = r.multiply(BigInteger.valueOf(n - i));
}
for (int i=2; i<=k; i++) {
r = r.divide(BigInteger.valueOf(i));
}

// System.out.println(n + "," + k + " = " + r);
return r;
}

```
解法 2: GEF (指数生成函数)。这是个排列问题所以用指数生成函数。
对于 a: 有 a0 个 a 要放。写成指数函数形式 e0=e^(a0)/a0!
同样对于 b: 有 a1 个 b 要放。写成指数函数形式 e1=e^(a1)/a1!
等等等等
最后到 z, 有 a25 个 z 要放,写成指数函数形式 e25=e^(a25)/a5!

根据指数生成函数的理论,整个排列数就是
E=e0*e1*...*e25,中项 e^(sum)/sum! 的系数。

那么
```
E=[e^(a0)/a0!][e^(a1)/a1!]*...*[e25=e^(a25)/a25!]
= [e^(a0+a1+...+a25)]/[a0!*a1!*...*a25!]
= [e^sum]/[a0!*a1!*...*a25!]
e ^ sum sum !
= --------------------------- * --------------------
a0! *a1!* ... * a25 !) sum!

e ^ sum sum !
= --------------------------- * --------------------------
sum! a0! *a1!* ... * a25 !
```
要求的系数就是 ( sum!)/( a0! *a1!* ... * a25 ! )

写成程序就是

```
// Solve by GEF
private long solve2(int[] a) {
// expr e0 = e^a0/a0!, e1 = e^a1/a1! ... etc
// E = e0*e1*e2 .... * e25
// e^(a0+a1+...+a25)/(a0!*a1*a2*....*a25!)
// ? = e^(a0 + a1 + ... + a25)/(sum!)
int sum = 0;
for (int c : a) {
sum += c;
}
BigInteger p = p(sum);
BigInteger c = BigInteger.ONE;
for (int i : a) {
c = c.multiply(p(i));
}
return p.divide(c).longValue();
}

private BigInteger p(int sum) {
BigInteger r = BigInteger.ONE;
for (int i= sum; i>=2; i--) {
r = r.multiply(BigInteger.valueOf(i));
}
return r;
}
```
简单写了个程序。题目没有讲太清楚(是否这些字母一定要全部使用)。这里为了简单就假设全部使用。

解法一:排列组合。生成字符串长度是 sum=a0+a1+a2+...+a25 。放 a,有(sum, a0)种选择的方法;放 b,有(sum - a0, a1)种方法;放 c,有(sum - a0 - a1, a2)种方法。。。。直到最后。

写出程序:

private long solve1(int[] letters) {
int sum = 0;
for (int c : letters) {
sum += c;
}
BigInteger r = BigInteger.ONE;
for (int c : letters) {
BigInteger s = choose(sum, c);
r = r.multiply(s);
sum -= c;
}
return r.longValue();
}

private static BigInteger choose(int n, int k) {
BigInteger r = BigInteger.ONE;
for (int i=0; i<k; i++) {
r = r.multiply(BigInteger.valueOf(n - i));
}
for (int i=2; i<=k; i++) {
r = r.divide(BigInteger.valueOf(i));
}

// System.out.println(n + "," + k + " = " + r);
return r;
}


解法 2: GEF (指数生成函数)。这是个排列问题所以用指数生成函数。
对于 a: 有 a0 个 a 要放。写成指数函数形式 e0=e^(a0)/a0!
同样对于 b: 有 a1 个 b 要放。写成指数函数形式 e1=e^(a1)/a1!
等等等等
最后到 z, 有 a25 个 z 要放,写成指数函数形式 e25=e^(a25)/a5!

根据指数生成函数的理论,整个排列数就是
E=e0*e1*...*e25,中项 e^(sum)/sum! 的系数。

那么 E=[e^(a0)/a0!][e^(a1)/a1!]*...*[e25=e^(a25)/a25!]
= [e^(a0+a1+...+a25)]/[a0!*a1!*...*a25!]
= [e^sum]/[a0!*a1!*...*a25!]
e ^ sum sum !
= --------------------------- * --------------------
a0! *a1!* ... * a25 !) sum!

e ^ sum sum !
= --------------------------- * --------------------------
sum! a0! *a1!* ... * a25 !

要求的系数就是 ( sum!)/( a0! *a1!* ... * a25 ! )

写成程序就是


// Solve by GEF
private long solve2(int[] a) {
// expr e0 = e^a0/a0!, e1 = e^a1/a1! ... etc
// E = e0*e1*e2 .... * e25
// e^(a0+a1+...+a25)/(a0!*a1*a2*....*a25!)
// ? = e^(a0 + a1 + ... + a25)/(sum!)
int sum = 0;
for (int c : a) {
sum += c;
}
BigInteger p = p(sum);
BigInteger c = BigInteger.ONE;
for (int i : a) {
c = c.multiply(p(i));
}
return p.divide(c).longValue();
}

private BigInteger p(int sum) {
BigInteger r = BigInteger.ONE;
for (int i= sum; i>=2; i--) {
r = r.multiply(BigInteger.valueOf(i));
}
return r;
}
数学方式直接算:应该是指数生成函数
19 天前
回复了 JasonLaw 创建的主题 Java 关于 StackOverflowError 和 OutOfMemoryError 的疑惑
jvm 通过-xss 指定每个线程使用的栈的大小(类似的 createThread api 同样可以指定栈的大小).记得默认 java 栈大小是 512kb,C++是 2MB. 栈的大小决定了函数调用的深度(因为 Java 不像 c++。c++要在栈上传递值或者引用。Java 只需要传递引用。所以 jvm 选择了一个较小的栈).

上文说的 outofmemory error 是针对一个虚拟机能创建的最多的线程数。因为栈是在 heap 上分配的,自然最大的线程数就约等于 xmx / xss 。
创建了这么多线程,再创建新的线程就会出现 outofmemory error 因为没有剩余的 heap 保留来做线程栈
jmap 看下是不是 heap 满了,100%是在不停的做 GC (按三楼的方法,会看到是 GC Thread 在占 cpu)
fluentbit, 够轻量了,找个简单点的后端,比如 mongodb 之类的,或者干脆 Linux 的 syslog/windows 的 event log
55 天前
回复了 RedBeanIce 创建的主题 程序员 [ Java 应用监控] springboot 的应用监控方案
micrometer + prometheus + grafana
MQ + Prepared Statement (需要比较新的 MySQL)
关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1463 人在线   最高记录 5168   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 15ms · UTC 17:18 · PVG 01:18 · LAX 10:18 · JFK 13:18
♥ Do have faith in what you're doing.