计算退房价格

Calculating check out price

对于这个程序,我们应该计算用户输入的项目的总价。我们正在使用获取范围双精度的方法和询问用户是否要继续的方法。以下是我使用的方法:

public static double getRangedDouble(Scanner src, String prompt, double lo, double hi)
    {
        double retVal = lo - 1;
        String trash;
        do
        {
            System.out.print(prompt + " " + lo + " - " + hi);
            if(src.hasNextInt())
            {
                retVal = src.nextInt();
            }
            else
            {
                trash = src.nextLine();
            }
        }while(retVal < lo || retVal > hi);

        return retVal;
    }

    public static Boolean getYNConfirm(Scanner src, String prompt)
    {
        String input = "";
        boolean done=true;

        System.out.println(prompt + " Y or N");
        while(!done)
        {
            input = src.nextLine();
            if(input.equalsIgnoreCase("Y"))
            {
                done=true;
            }
            else if(input.equalsIgnoreCase("N"))
            {
                done=false;
            }
            else
            {
                System.out.println("Y or N");
            }
        }
        return done;
    }

这是直接来自我的作业的描述:

At the 10$ store nothing is more than .00. Prompt the user for the price of their item (.50 cents to .99 dollars) using the getRangedDouble method and continue to input items as long as they indicate that they have more using your getYNConfirm method. Display the total cost of the item(s) to 2 decimal places with printf.

我知道如何使用程序中的方法,但我不知道如何让 getYNConfirm 方法起作用或如何在用户输入单独的价格时计算总价。任何帮助将不胜感激。

我只看到你的 getYNConfirm 方法的一种用法(这很奇怪),但其中隐藏了一个相当微妙的逻辑错误。

观察:

while(!done)

如果 donetrue,则上面的表达式为:

while(false)

...表示此循环将永远不会执行。

根据您到目前为止向我们展示的内容,解决方案非常简单,只需将 done 的初始状态转换为 false:

boolean done = false;

顺便说一句,通常您希望在绝对必要时 return 基元的盒装类型。在这种情况下,与 boolean.

相比,我认为 returning Boolean 没有任何价值

我不明白为什么这是一个无效的答案。我觉得这里的代码很容易解释。我添加了一些额外的推理,但我很乐意解释它是否有任何问题

于是代码如下

public static double getRangedDouble(Scanner src, String prompt, double lo, double hi)
{
    boolean valid = false;
    while( !valid ) {
        System.out.print(prompt + " " + lo + " - " + hi);
        if(src.hasNextInt())
            retVal = src.nextInt();
        else
            src.nextLine();

        if( retVal < 10 && retVal > 0.5 )
            valid = true;
    }

    return retVal;
}

public static Boolean getYNConfirm(Scanner src, String prompt)
{
    String input;
    boolean done = false;
    double total;
    DecimalFormat df=new DecimalFormat("#.##");

    while(!done) {
        System.out.println("Y or N");
        input = src.nextLine();

        if(input.equalsIgnoreCase("Y"))
            done=true;
        else if(input.equalsIgnoreCase("N")) {
            done=false;
            total += getRangedDouble( file, "Specify the price between:", 0.50, 9.99);
            System.out.println( "The total is:" + df.format( total ) );
        }
    }
    return done;
}

本质上,您想调用 getRangedDouble 来要求用户指定价格。您可以通过添加 return total += getRangedDouble

您要输入的参数是扫描仪、提示、下限和上限。

( file, "Specify the price between:", 0.50, 9.99);

getRangedDouble 中,您想在响应无效时获取用户输入。所以你是对的,继续阅读直到有下一个好的提示。

然后获取并检查他们的价格输入,直到获得所需的价格范围。

retVal < 10 && retVal > 0.5

当发生这种情况时,它是有效的。将值设置为 true,并 return retVal。要格式化总数,您需要做的就是使用 DecimalFormat。此行创建具有 #.## 指定小数点后 2 位精度的小数形式。

DecimalFormat df=new DecimalFormat("#.##");

然后您可以在打印时调用 df.format( total ) 格式化您的总数。

好的,让我们进入您的问题:

At the 10$ store nothing is more than .00. Prompt the user for the price of their item (.50 cents to .99 dollars) using the getRangedDouble method and continue to input items as long as they indicate that they have more using your getYNConfirm method. Display the total cost of the item(s) to 2 decimal places with printf.

对于这个级别的任何编码问题,要做的第一件大事就是将其分解成各个组成部分。对于这个问题,这些是:

  1. 能够向用户询问商品的价格(勾选)
  2. 能够询问用户是否还有其他项目要输入(勾选...见下文)
  3. 只要第二步为真,就循环以上2步(TODO)
  4. 能够对循环的每个价格步骤中给定的值求和(TODO)

对于第 1 步,我们有 getRangedDouble(...),它已签出。这里为了方便复制过来:

public static double getRangedDouble(Scanner src, String prompt, double lo, double hi){
  double retVal = lo - 1;
  String trash;
  do{
    System.out.print(prompt + " " + lo + " - " + hi);
    if(src.hasNextInt()){
       retVal = src.nextInt();
    } else {
       trash = src.nextLine();
    }
  } while(retVal < lo || retVal > hi);
  return retVal;
}

对于第 2 步,我们有 getYNConfirm(...) 方法,此处给出:

public static Boolean getYNConfirm(Scanner src, String prompt){
  String input = "";
  boolean done=true;
  System.out.println(prompt + " Y or N");
  while(!done){
    input = src.nextLine();
    if(input.equalsIgnoreCase("Y")){
      done=true;
    } else if(input.equalsIgnoreCase("N")) {
      done=false;
    } else {
      System.out.println("Y or N");
    }
  }
  return done;
}

不幸的是,这里面有一个逻辑错误。您将 done 初始化为 true,并且您的 while 循环结束了 while(!done) 条件。因此这是第一次 while(!true) --> while(false),它不执行。因此永远不会进入 while 循环,因此每次调用该方法时我们 return true。要解决此问题,请考虑在看到 "Y" 后要做什么 - 您最终会 return 为真。您的方法首先经历了打破循环的动作,但我们可以跳过该步骤并直接跳到 returning true。因此考虑这个版本的 getYN... 方法:

public static boolean getYNConfirm(Scanner src, String prompt){
  String input = "";
  System.out.println(prompt + " Y or N");
  while(true){ //Loops forever until a return or break statement 
    input = src.nextLine();
     if(input.equalsIgnoreCase("Y")){
       return true;
     } else if(input.equalsIgnoreCase("N")) {
       return false;
     } else {
       System.out.println("Y or N");
     }
   }
}

这符合您原始版本方法的意图,没有逻辑错误。

所以现在我们进入了大结局 - 使用上述两种方法编写一个方法作为循环并不断向用户询问更多价格的方法,并在进行时求和。让我们把这个方法写成 main(String[] args),这样我们就可以 运行 看看会发生什么。

我们想在这里使用一个循环,以允许用户继续输入价格直到完成。我们可以使用伪代码对我们的问题进行建模,如下所示:

while(user not done inputting prices){
    get next price
    add price to sum of prices
    ask the user if they would like to continue
}
print sum of prices

就像您可以调用内置方法并存储 rentVal = src.nextInt() 等输出结果一样,您可以对您编写的方法执行相同的操作。例如,我们可以要求用户使用 getRangedDouble(...) 输入下一个价格。根据我们编写的方法头,这个 return 是一个 double 类型的值,所以当我们存储这个调用的输出时,它应该在一个 double 变量中:double nextPrice = getRangedDouble(...);

如果伪代码有意义,后面的代码其实比较简单:

public static void main(String[] args){

  Scanner s = new Scanner(System.in); //Allow for reading user input from console

  boolean looping = true; //True so long as the user isn't done inputting prices.
                          //Initially true so that at least one price is entered
  double sum = 0.0;       //The sum of prices thus far
  while(looping){
    double nextPrice = getRangedDouble(s, "Enter a price in the range", 0.5, 10.0);
    sum = sum + nextPrice; //Add the price into the sum
    looping = getYNConfirm(s, "Add another item to your cart?");
  }
  System.out.println(String.format("%.2f", sum)); //Prints sum, limited to 2 decimal places
}