java - 为什么函数会在循环中被多次调用?

标签 java regex loops parsing processing

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

这是 Operation 类的 calculate() 方法:

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 的长度一样多。我知道问题出在 for 循环中的 pressedNumber boolean 值。我知道this question上的OP遇到了同样的问题,根据用户输入的长度打印多次,但问题的答案没有解释为什么这样做。

无效的研究和试验

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

更新

我对堆栈溢出进行了更多研究,这次是针对正则表达式,并将这些问题添加到我的研究中以解决此问题:

最佳答案

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

例如,看一下这个片段:

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

关于java - 为什么函数会在循环中被多次调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51996320/

相关文章:

java - 保护 Google Cloud Endpoints 免受未经授权用户的侵害

java - hibernate 以持久保存日期

java - Docx4J 从 docx 文件中获取页眉/页脚元素并修改它们

java - 后续第 2 部分——使用 Maven 仅对 jar 进行签名并将其部署到 Maven Central。构建和编译完全由 Ant 完成

ruby 正则表达式 : parsing C++ classes

javascript - 遍历列表并在 jQuery 为空时显示消息

javascript - 用正则表达式替换第 n 个匹配项

python - 匹配表示正则表达式集的模式

javascript - 使用全局标志将字符串文字作为 Javascript .replace() 模式传递

xcode - 遍历对象/变量 Swift