【问题标题】:How do I parse a string representing a sequence of arithmetic operations?如何解析表示算术运算序列的字符串?
【发布时间】:2011-09-24 23:31:19
【问题描述】:

我正在做一个个人项目,我想接受如下所示的用户输入:

   1.0+2.5+3--4 

并将其格式化为:

   1.0 + 2.5 + 3 - -4  

到目前为止,我正在使用 .replace("+") 到 .replace(" + ") 并为所有操作数执行此操作,但问题是它使用户输入:

  1.0 + 2.5 + 3 - - 4 

有没有办法可以用负号来实现。我想这样做,这样我就可以将数字解析为双精度数,然后在以后加减它们。

我的代码:

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


public class StringMan {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

    String check = "-a1 +a2 +       a3 +-a5";
    check  = check.replace("--", "+");
    System.out.println(check);
    Pattern pattern = Pattern.compile("\\s+");
      Matcher matcher = pattern.matcher(check);
      boolean expr = matcher.find();
      String str = matcher.replaceAll(" ");
      System.out.println(str);



}

   }

输出是:

   -a1 +a2 -       a3 +-a5
   -a1 +a2 - a3 +-a5

问题是我希望输出看起来像这样: -a1 + a2 - a3 + -a5

【问题讨论】:

    标签: java string double


    【解决方案1】:

    在这种特定情况下,您可以通过将 -- 替换为 + 来处理它们:

    1. 将用户输入作为字符串接收
    2. 删除所有空格
    3. 将所有-- 替换为+
    4. 根据需要继续解析

    【讨论】:

    • 问题是用户输入也可以是这个`-4+5-6'
    • 我不明白这是怎么回事。
    • 这不是问题。但是6*-2 可能是。
    • 我应该发布我目前所拥有的吗?我已经完成了 -- 部分,但在部分之前我试图弄清楚,因为我想要它们之间的空格,所以我可以应用 .split(" ");
    【解决方案2】:

    我建议使用正则表达式及其“组”功能。实际上,我会删除所有空格以使事情变得更容易,将其排除在等式之外,减少一件需要处理的事情。显然我会建议简化字符串,将“--”替换为“+”,将“*+”替换为“*”等等。

    现在您可以在清理后的字符串上使用正则表达式。

    Pattern firstPat = Pattern.compile("(((\\+|-)?)\\d+(.\\d+)?)");//for matching the first number, leading sign is optional
    Pattern remainingPat = Pattern.compile("(\\+|-)(\\d+(.\\d+)?)");//for remaining numbers, leading sign is mandatory.
    Pattern remainingPatWithExtOps = Pattern.compile("(\\*|/|\\+|-)(-?\\d+(.\\d+)?)");//for remaining numbers, accommodating multiply and divide with negative signs(positive signs should have been cleaned out)
    
    Matcher match = firstPat.matcher(inputString);
    

    现在您可以使用match.find() 方法遍历字符串。然后使用match.group(1) 获取符号/操作,并使用match.group(2) 获取数字...

    所以...

    Double firstnum;
    boolean firstNumSigned = false;
    if(match.find())
    {
        firstNum = Double.parse(match.group(0));// Parsing handles possible sign in string. 
        //obv check for exceptions during this and double check group num
        String tmp = match.group(1);
        firstNumSigned = tmp.equals("+") || tmp.equals("-");
    }
    else
    {//no match means the input was probably invalid....
        throw new IllegalArgumentException("What the heck were you thinking inputting that?!");
    }
    match = remainingPat.matcher(inputString);//use our other pattern for remaining numbers
    if(firstNumSigned)
    {
        match.find();//a signed first number will cause success here, we need to ignore this since we already got the first number
    }
    Double tmpRemaingingNum;
    String operation;
    while(match.find())
    {
        operation = match.group(1);
        tmpRemainingNum = Double.parse(match.group(2));
        //Do what you want with these values now until match.find() returns false and you are done
    }
    

    PS:代码未经测试,我对正则表达式相当有信心,但我不能 100% 确定第一个模式上的分组括号.. 可能需要试验

    【讨论】:

    • 字符串 a = "-1.0+-10"; Pattern firstPat = Pattern.compile("(+|-)?(\\d+(.\\d+)?)");//匹配第一个数字,前导符号可选 Pattern remainingPat = Pattern.compile("( +|-)(\\d+(.\\d+)?)");//对于剩余的数字,前导符号是强制性的。添加 * 和 / 如果你想适应这些功能。匹配器匹配 = firstPat.matcher(a); System.out.println(match);
    • 字符串 a 应该被简化为将“+-”变成“-”,就像我说的,我没有测试这段代码......
    • 哦,等等 nvm,我想我知道你得到了什么。您可能不得不转义“+”,因为它是一个量化元字符。即将进行编辑……已完成编辑。
    • 但是我该如何把它们放在一起呢?非常感谢你的帮助顺便说一句:)
    • 编辑和扩展以显示一些逻辑......它一点也不整洁,我什至没有编译它。但它应该显示一般流程。请注意分组括号有多么棘手,正则表达式中的括号确定组号,我不确定我是否正确计算了它们,因此您可能需要调整这些括号/数字....
    【解决方案3】:

    首先将 -- 替换为 +,这在数学上是等效的。或者首先将 -- 替换为 - -,这样可以将 - 和 4 保持在一起。

    【讨论】:

      【解决方案4】:

      检查这个, 读取运算符之间的字符串和整数,例如 '*,--,-,+" 我们可以读取整数和字符。

      public static void main(String[] args) {
          // TODO Auto-generated method stub
          final Pattern remainingPatWithExt=Pattern.compile("(\\p{L}\\p{M}*)[\\p{L}\\p{M}0-9^\\-.-?_+-=<>!;]*");
          String check = "a1+a2+--a7+    a3 +-a5";
      
            Matcher matcher = remainingPatWithExt.matcher(check);
            while( matcher.find())
            {
                System.out.println(matcher.group()); 
                  //use  matcher.group(0) or matcher.group(1)
            }
      
      }
      

      输出

      a1 a2 a7 a3 a5

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-06
        • 2015-08-25
        • 1970-01-01
        • 2018-07-06
        • 1970-01-01
        • 2019-03-24
        相关资源
        最近更新 更多