Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用随机发生器投掷硬币_Java - Fatal编程技术网

Java 使用随机发生器投掷硬币

Java 使用随机发生器投掷硬币,java,Java,我正试图编写一个模拟抛硬币的程序。第一次投币时,我希望程序退出。while循环中的第一个语句将掷硬币一次。然后我有一个if语句,它说如果我刚才掷的硬币是退出程序的。但是我的程序没有按我想要的方式运行。有时 我的问题是,在while循环中,我是每1个周期掷硬币一次还是两次?硬币是否在while循环中翻转一次,然后在if条件下再次翻转?我已经测试过了,但每次都有不同的错误,结果也不一样,我不知道为什么 if条件是否适合我在程序中尝试执行的操作 import acm.program.*; import

我正试图编写一个模拟抛硬币的程序。第一次投币时,我希望程序退出。while循环中的第一个语句将掷硬币一次。然后我有一个if语句,它说如果我刚才掷的硬币是退出程序的。但是我的程序没有按我想要的方式运行。有时

我的问题是,在while循环中,我是每1个周期掷硬币一次还是两次?硬币是否在while循环中翻转一次,然后在if条件下再次翻转?我已经测试过了,但每次都有不同的错误,结果也不一样,我不知道为什么

if条件是否适合我在程序中尝试执行的操作

import acm.program.*;
import acm.util.*;

public class CoinToss extends ConsoleProgram{
public void run(){


     while (true){
        println(flipCoin());
        if (flipCoin() == "heads"){
               break;
             }   
        }
  }

public String flipCoin(){
   String flip = rgen.nextBoolean() ? "heads" : "tails"; 
   return flip;
 }


public RandomGenerator rgen = RandomGenerator.getInstance();
}

每次调用
flipCoin()
时,该方法都会运行,因此它会在
println(flipCoin())行上运行一次和一次打开
if(flipCoin()=“heads”)
。两次调用的结果可能不同,您应该存储结果,然后使用结果,因此:

    while (true){
        String result=flipCoin();
        System.out.println(result);
        if (result.equals("heads")){
            break;
        }   
    }
还请注意,将==与字符串一起使用(在大多数情况下)将始终给出false;这是因为
==
询问它们是否是字面上相同的对象,而不是它们的内容是否相等(两张纸上都可以写“hi”,但它们不是同一张纸)
.equals
比较两个字符串的内容(即,如果它们说的是同一个单词)

<>我尽可能地将修改保持在您的代码附近,但您可能需要考虑以下可能的改进:

  • break
    可以有合法用途,但通常是不必要的,您可以通过以下方式避免:

    String result=flipCoin();
    while (result.equals("heads")==false){
        System.out.println(result);
        result=flipCoin();
    
    }
    
  • >p>再次使用字符串作为标识符有其位置,但考虑所有可用的不同的资本(头、头、头),枚举可能是更好的选择。


    不,这是错误的。您的代码当前正在翻转一枚硬币,打印值,然后翻转另一枚硬币以测试退出。问题是,如果你连续翻转两个线圈,你不一定总能得到相同的结果

    更好的方法是:

    for(;;)
        if(rgen.nextBoolean()) {
            println("heads");
            break;
        } else
            println("tails");
    
    您不需要单独的方法来实际翻转硬币,因为该方法已经存在,称为
    rgen.nextBoolean()
    。让方法返回一个字符串,然后处理该字符串,效率非常低。虽然效率与此无关,但不要养成这样的坏习惯,否则以后可能会被它咬到

    编辑:针对一些评论,这里有一种更通用、面向对象的方法:

    public enum CoinFlipResult {
        HEADS, TAILS;
        @Override
        public String toString(){ 
            switch(this){
            case HEADS: return "heads"; break;
            case TAILS: return "tails"; break;
            }
        } //could have just done `name().toLowerCase()`, but I like this better
    }
    
    public CoinFlipResult flipCoin(){
        if(rgen.nextBoolean())
            return CoinFlipResult.HEADS;
        else
            return CoinFlipResult.TAILS;
    }
    
    @Override
    public void run(){
        CoinFlipResult flip;
        do {
            flip = flipCoin();
            println(flip);
        } while(flip != CoinFlipResult.HEADS)
    }
    

    Me不喜欢不必要的
    break
    s和不要将字符串与==进行比较:

    String result = null;
    do {
        result = flipCoin()
        println(result);
    } while (!"tails".equals(result));
    

    我建议为“heads”和“tails”引入字符串常量

    在while循环中运行flipCoin()两次。同时请注意,您将字符串与==进行比较,请改用.equals()。对于我的个人文化,我是唯一一个不喜欢使用
    break
    语句的人吗?如果可以避免的话?@Bartdude是否有更优雅的方式退出程序而不是break?@Jessica使用导致
    break
    的条件,作为
    while
    循环中条件的一部分@巴特杜德:是的,
    break
    continue
    只是
    goto
    的花式版本,谢谢!我不敢相信我犯了那个错误。我的书中甚至有一节说,不要让.equals和==概念相互混淆。造成这一(常见)错误的原因之一是您的方法flipCoin()不仅翻转硬币,而且还获取硬币的状态。理想情况下,获取状态的操作应该与更改硬币状态的操作分开。这两个操作之间缺乏分离,因此很容易犯这样的错误。@RajeshJAdvani我同意,大概是一个Coin类,它有单独的.flip()和.getSide()方法。当然,这是相当多的开销,可能是值得的though@RichardTingle根据我的经验,对于大多数小的例子,像这种面向对象的设计,通常比像这样的直接方法有更多的开销。但在大多数情况下,随着例子的发展,这是值得的。哦,还有什么特别的原因要将布尔方法的结果与false进行比较吗?@MarcoForberg如果head和tails由enum表示(比如head和tails),那么为了清楚起见,您希望返回enum而不是布尔值,并将返回的值与特定的边进行比较。使用
    boolean
    进行比较是必要的,但是添加带有特定比较的枚举会使犯错误变得更加困难。@MarcoForberg一旦我阅读了其中一个答案,我立即意识到我的错误。真不敢相信我把==和.equals搞混了。谢谢您的帮助。@AJMansfield为什么要空for循环,因为这实际上是一段时间(真的)?此外,您还使多行无括号-???成为一种艺术形式,在不使用大括号的情况下将5行代码放入for循环。我印象深刻,但我不确定这对于可读性是否是一件好事:关于“方法返回字符串,然后处理字符串”,我同意它的速度较慢,但并非绝对是一件坏事,您实际上暗示了true==heads,但从未真正显式声明过它,这个假设可能会导致一个更大的程序,直到您开始必须在程序的一部分中有转换点true==heads,而在另一部分中true==tails。即使这些部分从未相遇,也更难阅读。当然字符串比较是不好的,可以避免,但是我认为有更好的方法来避免it@RichardTingle我添加了一个更好的版本。@RichardTingle IDK,我只是更喜欢它。@AJMansfield对此无可争辩,我们都有不同的编码风格+1用于枚举示例