【问题标题】:Why isn't my program returning the value of my expression?为什么我的程序没有返回我的表达式的值?
【发布时间】:2014-11-10 08:34:10
【问题描述】:

我目前正在学校学习 AP 计算机科学课程,但我的一个项目遇到了小麻烦!该项目要求我创建一个可以计算表达式然后求解它的计算器。我已经把大部分内容都写下来了,但是我遇到了一些麻烦,因为我的老师让我使用一个 while 循环来不断地要求输入并显示答案,而我被困住了。要结束程序,用户必须输入“退出”,我不能使用 system.exit() 或任何类似的作弊工具,程序必须用完代码。我也记下了其中的大部分内容,但是我无法在方法MethodToReadInput(); 中找到returnexpression 的原因。有人有任何提示吗?

import java.util.*;

public class Calculator {
   public static void main(String[] args) {
      System.out.println("Welcome to the AP Computer Science calculator!!");
      System.out.println();
      System.out.println("Please use the following format in your expressions: (double)(space)(+,-,*,/...)(space)(double)");
      System.out.println("or: (symbol)(space)(double)");
      System.out.println();
      MethodToReadInput();
      MethodToTestInput(MethodToReadInput());

   }

   public static String MethodToReadInput() {
      Scanner kb = new Scanner(System.in);
      System.out.print("Enter an expression, or quit to exit: ");
      String expression = kb.nextLine();
      if (expression.equalsIgnoreCase("quit")) {
         System.out.println("Goodbye!");
      }
      else {
         return expression; 
      }
   } 
   public static void MethodToTestInput(String expression) {
      while (!expression.equalsIgnoreCase("quit")) {
          MethodToReadInput();
          MethodtoEvaluateInput(expression);
      }
      System.out.println("Goodbye!");
   }



   public static void MethodtoEvaluateInput(String expression) {
      if (OperatorFor2OperandExpressions(expression).equals("+")) {
         System.out.println(FirstOperandFor2OperandExpressions(expression) + " " + OperatorFor2OperandExpressions(expression) + " " + SecondOperandFor2OperandExpressions(expression) + " = " + (FirstOperandFor2OperandExpressions(expression) + SecondOperandFor2OperandExpressions(expression)));          
      }
      else if (OperatorFor2OperandExpressions(expression).equals("*")) {
         System.out.println(FirstOperandFor2OperandExpressions(expression) + " " + OperatorFor2OperandExpressions(expression) + " "  + SecondOperandFor2OperandExpressions(expression) + " = " + (FirstOperandFor2OperandExpressions(expression) * SecondOperandFor2OperandExpressions(expression)));
      }
      else if (OperatorFor2OperandExpressions(expression).equals("-")) {
         System.out.println(FirstOperandFor2OperandExpressions(expression) + " " + OperatorFor2OperandExpressions(expression) + " " + SecondOperandFor2OperandExpressions(expression) + " = " + (FirstOperandFor2OperandExpressions(expression) - SecondOperandFor2OperandExpressions(expression)));       
      }
      else if (OperatorFor2OperandExpressions(expression).equals("/")) {
         System.out.println(FirstOperandFor2OperandExpressions(expression) + " " + OperatorFor2OperandExpressions(expression) + " "  + SecondOperandFor2OperandExpressions(expression) + " = " + (FirstOperandFor2OperandExpressions(expression) / SecondOperandFor2OperandExpressions(expression)));
      }
      else if (OperatorFor2OperandExpressions(expression).equals("^")) {
         System.out.println(FirstOperandFor2OperandExpressions(expression) + " " + OperatorFor2OperandExpressions(expression) + " " + SecondOperandFor2OperandExpressions(expression) + " = " + Math.pow(FirstOperandFor2OperandExpressions(expression),SecondOperandFor2OperandExpressions(expression)));
      }
      else if (OperatorFor1OperandExpressions(expression).equals("|")) {
         System.out.println(OperatorFor1OperandExpressions(expression) + " " + OperandFor1OperatorExpressions(expression) + " = " + Math.abs(OperandFor1OperatorExpressions(expression)));
      }
      else if (OperatorFor1OperandExpressions(expression).equals("v")) {
         System.out.println(OperatorFor1OperandExpressions(expression) + " " + OperandFor1OperatorExpressions(expression) + " = " + Math.sqrt(OperandFor1OperatorExpressions(expression)));
      }
      else if (OperatorFor1OperandExpressions(expression).equals("~")) {
         double x = 0.0;
         System.out.println(OperatorFor1OperandExpressions(expression) + " " + OperandFor1OperatorExpressions(expression) + " = " + (Math.round(OperandFor1OperatorExpressions(expression))+ x));
      }
      else if (OperatorFor1OperandExpressions(expression).equals("s")) {
         System.out.println(OperatorFor1OperandExpressions(expression) + " " + OperandFor1OperatorExpressions(expression) + " = " + Math.sin(OperandFor1OperatorExpressions(expression)));
      }
      else if (OperatorFor1OperandExpressions(expression).equals("c")) {
         System.out.println(OperatorFor1OperandExpressions(expression) + " " + OperandFor1OperatorExpressions(expression) + " = " + Math.cos(OperandFor1OperatorExpressions(expression)));
      }
      else if (OperatorFor1OperandExpressions(expression).equals("t")) {
         System.out.println(OperatorFor1OperandExpressions(expression) + " " + OperandFor1OperatorExpressions(expression) + " = " + Math.tan(OperandFor1OperatorExpressions(expression))); 
      } 
   }

      public static double FirstOperandFor2OperandExpressions(String expression) {
         String[] tokens = expression.split(" ");
         String OperandOrOperator = tokens[0];
         double y = Double.parseDouble(OperandOrOperator);
         return y;         
   }
      public static double SecondOperandFor2OperandExpressions(String expression) {
         String[] tokens = expression.split(" ");
         String OperandOrOperator = tokens[2];
         double y = Double.parseDouble(OperandOrOperator);
         return y;
   }
       public static String OperatorFor2OperandExpressions(String expression) {
         String[] tokens = expression.split(" ");
         String OperandOrOperator = tokens[1];
         return OperandOrOperator;
   }
      public static String OperatorFor1OperandExpressions(String expression) {
         String[] tokens = expression.split(" ");
         String OperandOrOperator = tokens[0];
         return OperandOrOperator; 
   }
      public static double OperandFor1OperatorExpressions(String expression) {
         String[] tokens = expression.split(" ");
         String OperandOrOperator = tokens[1];
         double y = Double.parseDouble(OperandOrOperator);
         return y;  
   }           
}

【问题讨论】:

  • 您的命名约定非常非常混乱。
  • 是混乱还是冗长?
  • 两者,方法都应该以小写开头,例如,不写underWaterExplisionBigWavesInTheOcean,你可以写tsunami
  • 方法通常也是动词,你描述的是它是什么而不是它做什么。请改用testInputreadInput
  • 请记得选择最佳答案

标签: java expression calculator helper tipsy


【解决方案1】:

您需要将MethodToReadInputMethodtoEvaluateInput 放在一个循环中。例如:

public static void main(String[] args)
{
    System.out.println("Welcome to the AP Computer Science calculator!!");
    System.out.println();
    System.out.println("Please use the following format in your expressions: (double)(space)(+,-,*,/...)(space)(double)");
    System.out.println("or: (symbol)(space)(double)");
    System.out.println();


    String input = MethodToReadInput();
    while (input != null)//exit the loop and the program when input is null
    {
        MethodtoEvaluateInput(input);//process the input
        input = MethodToReadInput();//ask the user for the next input
    }

}

public static String MethodToReadInput()
{
    Scanner kb = null;
    try
    {
        kb = new Scanner(System.in);
        System.out.print("Enter an expression, or quit to exit: ");
        String expression = kb.nextLine();
        if (expression.equalsIgnoreCase("quit"))
        {
            System.out.println("Goodbye!");
            return null;
        }
        else
        {
            return expression;
        }

    }
    finally
    {//always close the Scanner before leaving the method
        if (kb != null)
            kb.close();
    }
}

此外,您应该遵循 Java Naming Convention 并为您的方法使用较短的名称。

【讨论】:

    【解决方案2】:

    尝试简化您的代码,并使用 do-while-loop 代替 while-loop 应该产生更好的代码,do while 将至少执行一个循环,然后在执行下一个循环之前检查下一个条件,但 while 将检查条件优先,如果没问题,它将执行循环。所以这里是代码:

    public class Calculator {
        public static void main(String[] args) throws IOException {
            System.out.println("Welcome to the AP Computer Science calculator!!");
            System.out.println();
            System.out.println("Please use the following format in your expressions: (double)(space)(+,-,*,/...)(space)(double)");
            System.out.println("or: (symbol)(space)(double)");
            System.out.println();
    
            String expression = "";
            do {
                Scanner kb = new Scanner(System.in);
                System.out.print("Enter an expression, or quit to exit: ");
                expression = kb.nextLine();
                if (expression.equalsIgnoreCase("quit")) 
                    System.out.println("Goodbye!");
                else 
                    MethodtoEvaluateInput(expression);              
            } while (!expression.equalsIgnoreCase("quit"));
            inRn.close();
            inSw.close();
        }
    }
    

    【讨论】:

      【解决方案3】:

      这样做:

       public static String MethodToReadInput() {
            Scanner kb = new Scanner(System.in);
            System.out.print("Enter an expression, or quit to exit: ");
            String expression = kb.nextLine();
            if (expression.equalsIgnoreCase("quit")) {
               System.out.println("Goodbye!");
               return "";
            }
            else {
               return expression; 
            }
      

      通过返回一个空字符串,您知道当用户想要退出时要查找什么。它必须是您返回的空字符串,因为您的方法应该返回一个字符串。还需要添加此 return 语句,因为编译器会抱怨,否则可能会在没有实际到达 return 语句的情况下到达非 void 函数(返回某些东西的东西)的末尾(所以当您输入 if 语句时)现在)。如果指定返回类型,则必须为所有可能性指定返回情况。换句话说,你必须始终如一言归。

      【讨论】:

        【解决方案4】:

        有几件事情需要解决。

        首先,让我们回答您的实际问题。您可以有多种选择。

        • 您可以简单地返回用户输入的任何内容。事实上,您可能实际上并不需要该方法。但无论如何,如果您的方法返回“quit”,while 循环可以像现在一样检查while ( ! expression.equals("quit") )
        • 您可以返回空值。这表明“表达式不是实际表达式”。那么你的 while 可能是while ( expression != null ),这比字符串比较更有效。

        但是您的程序还有其他设计问题:

        1. 您一次又一次地调用相同的方法来检索相同的内容。这些方法一次又一次地拆分字符串 - 一个相对繁重的操作。您可能应该只有一个 parseExpression() 方法来返回您的标记,然后测试这些标记是代表一元运算符还是二元运算符。大致如下:

          String [] tokens = parseExpression( expression );
          
          if ( isUnaryExpression( tokens ) ) {
               String operator = tokens[0];
               String operand = tokens[1];
               // Do something with operator and operand.
          } else if ( isBinaryExpression( tokens ) ) {
               String operator = tokens[1];
               String operand1 = tokens[0];
               String operand2 = tokens[2];
               // Do something with operator and operands {
          } else {
               System.err.println( "Bad expression!" );
          }
          
        2. 您从主服务器调用 MethodToReadInput 两次。这意味着它将读取一个输入,不做任何处理,然后读取另一个将传递给MethodToTestInput 的输入。挂断第一个电话,没必要。

        3. 为了更好的封装,main 方法实际上甚至不应该调用MethodToReadInput。调用该方法应该成为MethodToTestInput 的责任。因此,您只需从main 调用MethodToTestInput(),根本不需要传递任何参数。

        所以结构应该是:

        • ma​​in:显示介绍,调用你的循环方法。
        • 循环方式:调用输入法。 Loop while 返回的表达式仍然是一个表达式,而不是"quit"。在循环内部,调用表达式处理方法。
        • 表达式处理方法:调用parseExpression() 方法,检查标记是什么,进行数学运算。

        最后,关于您的命名问题:

        • 在 Java 中,我们只命名首字母大写的类。常量以全部大写(单词用下划线分隔)命名。方法名称以小写字母开头。
        • 您没有命名方法MethodThatDoesThis。您应该将其命名为 doThis。这使阅读您的代码更容易,因为它实际上描述了正在发生的事情。所以我将这些方法命名为:

          • 输入法:getNextExpression
          • 循环方法:runCalculator,或doCalculatorMainLoop或类似的东西。
          • 表达式处理方法:parseAndCalculate

          或者类似的东西。

        【讨论】:

          猜你喜欢
          • 2022-09-27
          • 2020-04-30
          • 1970-01-01
          • 2011-08-09
          • 1970-01-01
          • 2015-05-09
          • 1970-01-01
          • 2018-05-29
          • 1970-01-01
          相关资源
          最近更新 更多