Я протестировал эту программу на Java, и она работает:
import java.util.Random;
/** @author Daniel Trebbien */
// License: Public Domain
public class SO2965185 {
public static String randomFormat(final String templ) {
int i = templ.indexOf('{');
if (i < 0) {
return templ;
}
else {
Random r = new Random();
int prevI = 0;
StringBuilder sb = new StringBuilder();
do {
sb.append(templ, prevI, i);
int j = templ.indexOf('}', i + 1);
if (j < 0)
throw new java.util.MissingFormatArgumentException(templ.substring(i));
int pipeCount = 0;
for (int k = templ.indexOf('|', i + 1); i < k && k < j; k = templ.indexOf('|', k + 1))
++pipeCount;
if (pipeCount == 0) {
sb.append(templ, i + 1, j);
}
else {
String m0Selection;
final int m0 = r.nextInt(pipeCount + 1); // must pick one from each set
if (m0 >= pipeCount) {
m0Selection = templ.substring(templ.lastIndexOf('|', j - 1) + 1, j);
}
else {
int k = i + 1;
int m = m0;
for(; m > 0; --m)
k = templ.indexOf('|', k) + 1;
m0Selection = templ.substring(k, templ.indexOf('|', k + 1));
}
int selectionCount = 0;
for (int n = 0; n <= pipeCount; ++n) {
if (n == m0) {
if (selectionCount != 0)
sb.append(", ");
sb.append(m0Selection);
++selectionCount;
}
else if (r.nextBoolean()) {
int m = n;
if (selectionCount != 0)
sb.append(", ");
if (m >= pipeCount) {
sb.append(templ, templ.lastIndexOf('|', j - 1) + 1, j);
}
else {
int k = i + 1;
for(; m > 0; --m)
k = templ.indexOf('|', k) + 1;
sb.append(templ, k, templ.indexOf('|', k + 1));
}
++selectionCount;
}
}
}
prevI = j + 1;
i = templ.indexOf('{', j + 1);
} while(i >= 0);
return sb.toString();
}
}
public static void main(String[] args) {
System.out.println(randomFormat("test"));
System.out.println(randomFormat("{oneOption}"));
System.out.println(randomFormat("{first|second}"));
String s1 = "planets {Sun|Mercury|Venus|Earth|Mars|Jupiter|Saturn|Uranus|Neptune}{?|!|.}";
System.out.println(randomFormat(s1));
//System.out.println(randomFormat("jjj{test"));
}
}
Эта программа печатает что-то вроде:
test
oneOption
first, second
planets Sun, Mercury, Jupiter, Neptune?, !, .
и
test
oneOption
second
planets Sun, Jupiter, Saturn!, .
и
test
oneOption
first
planets Venus, Earth, Jupiter, Saturn, Uranus, Neptune.
Вам придется немного простить беспорядок, потому что я изначально написал код для немного другой проблемы:)
Код выбирает случайные комбинации записей, имеющих по крайней мере одну запись из каждого набора. Таким образом, для набора с N записей можно сгенерировать 2 N - 1 комбинаций. Кроме того, имейте в виду вероятность того, что в случайной комбинации есть ровно M записей:
P (в точности M записей в сгенерированной комбинации) = ( N выберите M ), деленное на (2 N - 1)
Пример: N = 9 ("{Sun|Mercury|Venus|Earth|Mars|Jupiter|Saturn|Uranus|Neptune}"
).
P (ровно 2 записи в сгенерированной комбинации) = 0.0704