数组/循环正确编译,但是如何保持输出的一部分相同?

时间:2018-11-17 07:01:43

标签: java arrays eclipse loops

也许我还不够清楚。我道歉。我尝试压缩并在此编辑中添加图像以使其更加清晰。

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();

1 个答案:

答案 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短,但使用相同的种子时则不会。然后可以使用该确定的值来切成给定的输出长度。

如果我误解了这种方法,我表示歉意。