首页 > 解决方案 > 为什么函数在循环中被多次调用?

问题描述

我使用处理开发环境制作了一个图形计算器应用程序,并包含了一个 JavaOperation类。Operation然后我在我的主文件-calculator.pde 中调用了该类的实例。当我在多个实例上调用该方法时,有条件地,由于调用该方法的循环和条件,它会多次打印该方法的输出。

这是类的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,它会输出:

突出显示所需输出的控制台输出

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

这是我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上的 OP也有同样的问题,它会根据用户输入的长度打印多次,但问题的答案并没有解释它为什么这样做。

无效的研究和试验

解决这个问题的一部分是将它processStatement变成一个变量,因为之前我只是在条件中打印它。这不起作用,因为它打印了多次。我不能println对方法内部的语句执行此操作,因为它们依赖于方法内部的变量,并且语句相当多。我的第二个计划是创建一个静态方法printInfo(),但这也行不通,因为变量的范围太窄,我不能在外面定义它们,因为那样会不准确。

更新

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

标签: javaregexloopsparsingprocessing

解决方案


以下是您可能需要在代码中重新考虑的一些事项:

例如,看看这个片段:

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


推荐阅读