为什么我的程序没有返回表达式的值?

时间:2014-11-10 08:34:10

标签: java expression calculator helper tipsy

我目前正在我的学校参加AP计算机科学课程,我的一个项目遇到了一些麻烦!该项目要求我创建一个计算器,可以评估表达式然后解决它。我已经完成了大部分工作,但我遇到了一点麻烦,因为我的老师让我使用while循环来不断询问输入并显示答案,我坚持这一点。要结束程序,用户必须键入“退出”,我不能使用system.exit()或任何作弊的东西,程序必须用完代码。我的大部分内容也是如此,但我无法找到return方法expression中的MethodToReadInput();为什么有人提出任何提示?

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;  
   }           
}

4 个答案:

答案 0 :(得分: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并为您的方法使用较短的名称。

答案 1 :(得分:0)

这样做:

 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语句,因为编译器会抱怨,因为它可能会到达非void函数的末尾(返回某些东西),而不会实际到达return语句(所以当你输入if语句时)它现在)。如果指定返回类型,则必须为所有可能性指定返回大小写。换句话说,你必须总是回复你所说的话。

答案 2 :(得分:0)

尝试简化你的代码,并使用do-while-loop代替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 :(得分:0)

有几件事情需要解决。

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

  • 您只需返回用户输入的内容即可。实际上,您可能实际上并不需要这种方法。但无论如何,如果你的方法返回"退出",while循环可以像现在一样检查while ( ! expression.equals("quit") )
  • 您可以返回null。这表明"表达式不是实际的表达式"。那么你的时间可能是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的责任。因此,您只需从MethodToTestInput()调用main,而无需传递任何参数。
  4. 所以结构应该是:

    • main :显示介绍,调用循环方法。
    • 循环方法:调用输入法。返回表达式时循环仍然是表达式而不是"quit"。在循环内部,调用表达式处理程序方法。
    • 表达式处理程序方法:调用parseExpression()方法,检查令牌是什么,做数学运算。

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

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

      • 输入法:getNextExpression
      • 循环方法:runCalculatordoCalculatorMainLoop或类似的东西。
      • 表达式处理程序方法:parseAndCalculate

      或者沿着这些方向发展。