为什么在循环中多次调用该函数?

时间:2018-08-24 01:33:09

标签: java regex loops parsing processing

我已经使用Processing Development Environment开发了一个图形计算器应用程序,并结合了Java Operation类。然后,我在主文件-Calculator.pde中调用了Operation类的实例。 当我在多个实例上有条件地调用该方法时,由于调用该方法的循环和条件,它会多次打印该方法的输出。

这是calculate()类的Operation方法:

String calculate() {
    int operationIndex = userInput.indexOf(operationSymbol);
    ArrayList<String> clickedNumbers = new ArrayList<String>();
    System.out.println(operation + " index: " + operationIndex);
    for (int i = 0; i < operationIndex; i++) {
      clickedNumbers.add(userInput.get(i));         }
    double double1 = calculator.stringToDouble(String.join("", clickedNumbers)); 
    System.out.println("double1: " + double1);
    clickedNumbers.clear();
    int equalsIndex = userInput.indexOf("=");
    for (int i = operationIndex + 1; i < equalsIndex; i++) {
      clickedNumbers.add(userInput.get(i));
    }
    double double2 = calculator.stringToDouble(String.join("", clickedNumbers)); 
    System.out.println("double2: " + double2);
    Double operResult = this.doOperation(double1, double2);
    String operationResult = calculator.doubleToString(operResult);
    System.out.println("Operation Result: " + operationResult);
    return operationResult;
}

所有System.out.println()语句都依赖于方法内部的局部变量。这些应该只打印到控制台一次。每当用户进行操作并按等于时,例如,如果她/她输入了15 * 3,它将输出:

Output of Console with desired output highlighted

上面,控制台输出中突出显示的部分是我想要的输出。

这是我的代码,其中调用calculate()方法:

  String[] numberStr = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};
  Boolean pressedEquals = listName.contains("=");

  for(String number : numberStr) {
  Boolean pressedNumber = listName.contains(number);
    if (pressedNumber && pressedEquals) {
      if (listName.contains("+")) {
        processStatement = "Adding Numbers...";
        result = addition.calculate();
      }
      else if (listName.contains("-")) {
        processStatement = "Subtracting Numbers...";
        result = subtraction.calculate();
      }
      else if (listName.contains("*")) {
        processStatement = "Multiplying Numbers...";
        result = multiplication.calculate();
      }
      else if (listName.contains("/")) {
        processStatement = "Dividing Numbers...";
        result = division.calculate();
      }
      else if (listName.contains("%")) {
        processStatement = "Modulufying Numbers...";
        result = modulus.calculate();
      }
      else if (listName.contains("^")) {
        processStatement = "Expounding numbers...";
        result = exponential.calculate();
      }
    } 
  }

我不明白为什么打印输出的次数是userInput ArrayList的长度。我知道问题是pressedNumber循环中的for布尔值。我知道this question上的OP存在相同的问题,它会根据用户输入的长度进行多次打印,但是对该问题的回答并不能解释为什么这样做。

无效的研究和试验

解决此问题的一部分是使processStatement成为变量,因为之前我只是在条件内打印了它。这没有用,因为它打印了多次。我无法对方法中的println语句执行此操作,因为它们取决于方法中的变量,并且有很多语句。我的第二个计划是制作一个静态方法printInfo(),但是由于变量的作用域范围太小,所以这也行不通,而且我不能在外部定义它们,因为那样会不准确。

更新

这次,我更多地关注堆栈溢出,正则表达式,这些问题添加到我的研究中以解决此问题:

1 个答案:

答案 0 :(得分:1)

以下是您可能需要在代码中重新考虑的几件事:

例如,查看以下代码段:

String[] numberStr = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};
Boolean pressedEquals = listName.contains("=");

for(String number : numberStr) {
    Boolean pressedNumber = listName.contains(number);
    // ...
}

您在这里不需要此循环。您可以简单地验证listName是否包含数字,运算符,即它是有效的表达式。并且,如果有效,则只需调用calculate()方法。您还可以使用基于正则表达式的验证来强制执行特定的表达式格式。

跳过该循环,然后执行验证,如下所示:

// Validate expression format here
// Example: <number> <operator> <number> <=>
//             1          *        5      =

final boolean isValidated = isValidExpression( /* expression */ );

if ( isValidated == true )
{
    final String op = /* get operator here */;
    switch ( op )
    {
        case "+":
            result = addition.calculate();
            break;

        case "-":
            result = subtraction.calculate();
            break;

       // ... /, *, % ...

        default:
            // ERROR: Invalid operator...
    }
}

除此之外,您还可以使用基于堆栈的表达式求值。


更新:

下面是使用正则表达式的isValidExpression()方法的示例:

// Test to validate expression with regex
// Example: <number> <operator> <number> <=>
//             1          *        5      =

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class ExpressionValidator
{
    public static boolean isValidExpression( final String exp )
    {
        final String regex = "\\d+\\s*[*|/|+|-]\\s*\\d+\\s*[=]";
        final Pattern pattern = Pattern.compile( regex );
        final Matcher matcher = pattern.matcher( exp.trim() );
        return matcher.find();
    }

    public static void main( final String[] args )
    {
        final String[] expressions = 
        {  
            " 1 +  2 =",
            " 3 *  5 =",
            "12 + 10 =",
            " 33 = 25 ",
            " +65  65 ",
            "45 666  ="
        };

        for ( final String exp : expressions )
        {
            System.out.println( "[" + exp + "] >> " + isValidExpression( exp ) );
        }
    }
}

输出:

[ 1 +  2 =] >> true
[ 3 *  5 =] >> true
[12 + 10 =] >> true
[ 33 = 25 ] >> false
[ +65  65 ] >> false
[45 666  =] >> false

这是实时示例:https://ideone.com/S9Wf9b