也许我还不够清楚。我道歉。我尝试压缩并在此编辑中添加图像以使其更加清晰。
50 Seed Value, 1200 RNG Value.
60 Seed Value, 1200 RNG Value.
在上面的示例中(为清楚起见,而不是全部写出来),您可以看到50和60的输出。这不是我关注的不同值。现在是显示器。如您所见,自从我输入了新的种子值以来,这个数字越来越大。我希望它显示50种子值是什么,但具有我输入的任何种子值的属性。
如果我输入例如60,我想得到:
H1 T1 H1 T1 HHH3 TTTTT5 H1 T1 HHHH4 T1 HH2 T1 H1 T1 H1 T1 H1 T1 H1 TTT3 H1 TTT3 H1 TTTT4 H1 T1 HHH3 TT2 H1 T ...(就像50种子值一样。)
但是它将获得35个不同的值,而不是30个。请让我知道,如果我更清楚的话,我为此感到困惑。
import java.util.Scanner;
import java.util.Random;
public class CoinFlipAnalyzer{
private static final Scanner
stdIn = new Scanner(System.in);
public static void main (String[] args){
// Integer Values:
int totalNumberOfRuns = 0;
int run = 1;
// Boolean Values:
boolean theCoin;
boolean tempVal = false;
// Gathering the Users Input:
System.out.println("Welcome to the coin flip analyzer.\n"
+ "How many flips?");
int numberOfFlips = stdIn.nextInt();
System.out.println("What do you want to seed the random number generator with?");
int rngSeed = stdIn.nextInt();
Random rng = new Random(rngSeed); // Initiates the Random Number Generator.
System.out.println();
// Loop and Array to Decide Whether the Value is Heads or Tail.
long[] runLength = new long[numberOfFlips];
for (int i = 0; i < numberOfFlips; i++) {
theCoin = rng.nextBoolean(); // As requested, I used the nextBoolean expression.
if (theCoin != tempVal) {
if (i > 0) {
System.out.print(run + " ");
}
runLength[run - 1]++;
totalNumberOfRuns++;
run = 1;
}
else {
run++;
}
if (theCoin) {
System.out.print("H");
tempVal = true;
}
else {
System.out.print("T");
tempVal = false;
}
}
System.out.print("...");
System.out.println();
System.out.println("There were a total of " + totalNumberOfRuns +
" distinct runs in the simulation.\nTheir breakdown follows:");
System.out.println();
答案 0 :(得分:1)
我认为我理解要求。从本质上讲,存在一些所需的宽度,如果输出的数量超过该宽度,则使用椭圆打印。
有StringUtils from Apache Commons带有“缩写”方法。
public static String abbreviate(String str, int maxWidth)
使用省略号缩写字符串。这会将“现在是所有好男人的时间”变成“现在是...的时间”。
要使用此命令(或下面的其他建议),我将删除运行中正在生成的即时输出,而是构建一个String
。一个人也可以构建一个char[]
,但是这里我们将使用一个String
(或StringBuilder
)。这样做还有另一个好处-将一些逻辑与输出分开通常是一个好习惯。另外,它将更具可测试性。
因此,如果可以使用StringUtils.abbreviate(...)
,则从doFlips(...)
中获取结果并将其传递给该方法,即可完成结果。
/*
* moved the flipping into a method; allow it to build the
* results rather than immediately outputting them
*/
private static StringBuilder doFlips(int numberOfFlips, Random rng)
{
long[] runLength = new long[numberOfFlips];
boolean theCoin;
boolean tempVal = false;
int run = 1;
int totalNumberOfRuns = 0;
// Here we will collect the output; use better name in production
StringBuilder sb = new StringBuilder();
for (int i = 0; i < numberOfFlips; i++) {
theCoin = rng.nextBoolean(); // As requested, I used the nextBoolean
// expression.
if (theCoin != tempVal) {
if (i > 0) {
sb.append(run);
sb.append(" ");
}
runLength[run - 1]++;
totalNumberOfRuns++;
run = 1;
}
else {
run++;
}
if (theCoin) {
sb.append("H");
tempVal = true;
}
else {
sb.append("T");
tempVal = false;
}
}
return sb;
}
如果无法使用该库,则编写一个chop
方法很容易:
/**
* Chop the input StringBuilder and give "..." at
* maxOutput.
*
* NOTE: no error checking
*/
private static String ourChop(StringBuilder sb, int maxOutput)
{
if (sb.length() <= maxOutput) {
return sb.toString();
}
// we chop everything past maxOutput - 3
sb.setLength(maxOutput - 3);
sb.append("...");
return sb.toString();
}
因此,我们可以执行以下操作:
public static void main(String[] args)
{
int seed = 1200;
int maxOutput = 25;
// 50 flips, 25 length max, including ... if needed
StringBuilder res = doFlips(50, new Random(seed));
System.out.println(ourChop(res, maxOutput));
res = doFlips(60, new Random(seed));
System.out.println(ourChop(res, maxOutput));
我们得到此输出(25点):
H1 T1 H1 T1 HHH3 TTTTT...
H1 T1 H1 T1 HHH3 TTTTT...
现在,如果目标是与某个给定运行的最大输出对齐,则需要收集所有运行(50、60等),然后找到特定值(例如输出;请注意,理论上,在真正随机的环境中,60的输出可能比50短,但使用相同的种子时则不会。然后可以使用该确定的值来切成给定的输出长度。
如果我误解了这种方法,我表示歉意。