将此字符串作为输入:
string s1="planets {Sun|Mercury|Venus|Earth|Mars|Jupiter|Saturn|Uranus|Neptune}{?|!|.}"
string s2="some text {morning,night,evening} some text{?|!|.}"
如何从集合中随机选择N,然后用逗号连接它们。该集合在{}之间定义,选项由|分隔管 订单得以维持。字符串可以有多个集{}。
一些输出可能是:
string output1="planets Sun, Venus.";
string output2="planets Neptune!";
string output3="planets Earth, Saturn, Uranus, Neptune.";
string output4="planets Uranus, Saturn.";// bad example, order is not correct
string output5="some text morning!";
Java 1.5
答案 0 :(得分:3)
将行星粘在一个数组中,然后移除随机元素,直到你有足够的数量。从算法上讲,有一些可行的解决方案,但是对于你正在处理的数据量,这很简单。
答案 1 :(得分:0)
我不确定java的语法 - 但它应该是这样的。
string[] split = s.split("|");
Random r = new Random();
int first = r.nextInt(split.length);
string planets = "planets " + split[first++];
for (; first < split.length; first++)
{
if (r.nextInt(2) == 1)
planets += " " + split[first];
}
答案 2 :(得分:0)
我测试了这个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
答案 3 :(得分:0)
这是另一种选择。这个只从{|||}
集合中选择1个元素,并在{,,,}
集合中选择1到N个元素,用逗号分隔它们。很好的编程挑战。
public static String generateVariant(String s) {
Pattern p = Pattern.compile("[{]([^}]+)[}]");
Matcher m = p.matcher(s);
StringBuilder output = new StringBuilder();
int offset = 0;
while (m.find()) {
output.append(s.substring(offset, m.start()));
String[] choices = m.group(1).split("[|,]");
// if '|' used as separator, only echo 1 random choice
int n = m.group(1).contains("|") ? 1
: (int) (Math.random() * (choices.length - 1)) + 1;
// permutation with n random elements
int[] permutation = new int[choices.length];
for (int i = 0; i < choices.length; i++) {
permutation[i] = i;
}
for (int i=0; i<n; i++) {
int r = (int)(Math.random() * (choices.length - i)) + i;
int aux = permutation[r];
permutation[r] = permutation[i];
permutation[i] = aux;
}
// sort and echo first n
Arrays.sort(permutation, 0, n);
for (int i=0; i<n; i++) {
output.append((i == 0 ? "" : ", ") + choices[permutation[i]]);
}
offset = m.end();
}
output.append(s.substring(offset, s.length()));
return output.toString();
}
public static void main(String[] args) {
String s1 = "planets {Sun,Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune}{?|!|.}";
for (int i = 0; i < 10; i++) {
System.err.println(generateVariant(s1));
}
}
是的,生成排列对{|||}
集来说是过度的。这是一个更短更简单的版本,其中选择数量的分布不再统一(受Daniel Trebbien的回答启发):
public static String generateVariant(String s) {
Pattern p = Pattern.compile("[{]([^}]+)[}]");
Matcher m = p.matcher(s);
StringBuilder output = new StringBuilder();
Random r = new Random();
int offset = 0;
while (m.find()) {
output.append(s.substring(offset, m.start()));
String[] choices = m.group(1).split("[|,]");
// if '|' used as separator, only echo 1 random choice
if (m.group(1).contains("|")) {
output.append(choices[r.nextInt(choices.length)]);
} else {
boolean first = true;
for (int i=0; i<choices.length; i++) {
if (r.nextBoolean()) {
output.append((first ? "" : ", ") + choices[i]);
first = false;
}
}
}
offset = m.end();
}
output.append(s.substring(offset, s.length()));
return output.toString();
}
答案 4 :(得分:0)
对于行星,只需写一个循环
result = empty list
For p in planets
throw a dice
If (dice > 3) // 50% probability, adjust as required
append p to result
If result is empty, start over // do this if you don't want result to be empty
这给出了一个随机的行星列表,按顺序给出。