【问题标题】:How to split string at operators如何在运算符处拆分字符串
【发布时间】:2014-01-15 18:38:10
【问题描述】:

我正在用 Java 创建一个计算器。

如果我让用户输入一个字符串,例如:

7+4-(18/3)/2

到目前为止,我必须让用户在每个数字或运算符之间输入一个空格。 我将如何从给定的字符串创建一个数组,其中字符串以数字或运算符拆分,所以在这种情况下,数组将是:

[7, +, 4, -, (, 18, /, 3, ), /, 2]

(数组是字符串类型)

任何帮助将不胜感激

谢谢:)

【问题讨论】:

  • 你会用那个数组做什么?如果您正在尝试评估表达式,那么已经有可用的库。
  • String[] splitted= userString.split(" "); 给出你的结果。但更喜欢像@Rohit 所说的那样使用现有的库。
  • @sᴜʀᴇsʜᴀᴛᴛᴀ 如果他的所有字符串都没有空间,那将有什么帮助?
  • @sᴜʀᴇsʜᴀᴛᴛᴀ 不,它没有。确实没有空间。
  • 但这肯定需要用户输入的字符串中已经存在空格?

标签: java arrays string split calculator


【解决方案1】:

试试这个:

String[] temp = expression.split("[\s+-\\\(\)]+");

将分开:

  • 空格
  • +运营商
  • -运营商
  • \ 字符
  • (字符
  • )字符

【讨论】:

  • 您好,感谢您的快速回复。当我尝试您的代码时,我收到错误:无效的转义序列(有效的是 \b \t \n \f \r \" \' \\ )您对导致此问题的原因有任何想法吗?
  • 非常感谢,如何还包括 * 运算符?我也再次遇到同样的错误。
  • 在方括号中添加\*
  • 这种方法的问题是它会剥离操作员。
  • -1:不编译且不符合 OP 的要求。看看我的回答。
【解决方案2】:

您尚未指定要对数组执行的操作。如果您真的想评估表达式,那么已经有可用的库。您可以使用其中之一。但是,如果您只想要一个像您展示的那样的数组,那么我也不建议使用正则表达式。您可以编写自己的解析器方法,如下所示:

public static String[] parseExpression(String str) {
    List<String> list = new ArrayList<String>();
    StringBuilder currentDigits = new StringBuilder();

    for (char ch: str.toCharArray()) {
        if (Character.isDigit(ch)) {
            currentDigits.append(ch);
        } else {
            if (currentDigits.length() > 0) {
                list.add(currentDigits.toString());
                currentDigits = new StringBuilder();
            }
            list.add(String.valueOf(ch));
        }
    }

    if (currentDigits.length() > 0)
        list.add(currentDigits.toString());

    return list.toArray(new String[list.size()]);
}

现在这样称呼它:

String str = "7+4-(18/3)/2";
System.out.println(Arrays.toString(parseExpression(str)));

你会得到你的结果。

【讨论】:

  • 非常感谢您的快速响应,它似乎按预期进行。但是,当我输入一个表达式时,例如 (7-9)/2 它返回 [(, 7, -, 9, ), /],你知道它为什么会离开 2 吗?谢谢:)
  • 每当表达式以数字结尾时似乎都会发生这种情况
  • @user3120023 在for 循环之外,检查currentDigits 是否为空。如果不是,则末尾有数字。将编辑代码。
  • 非常感谢 :) 但是,它似乎将诸如 2.5 之类的小数拆分为 [2, ., 5 ] 有什么解决方案吗?
【解决方案3】:

老实说,我这样做的方法就是自己扫描字符串。无论如何,您都希望从结果中构建一个操作,这样您就不会通过使用自动解析器/拆分器/等来真正获得任何东西。

这是代码的粗略草图:

List<Operations> ops = new ArrayList();

for (int i=0;i<str.length();i++) {

   char c = str.get(i);
   if (c == '.' || c >= '0' || c<='9') {
       // extract a number, moving i onwards as I do 
       // insert number into ops (new Operation(num))
   } else if (c!= ' ') {
       Operator operator = operators.get(c);
       if (operator == null) {
           // Handle invalid input - could just skip it
       } else {
           // Add operator to ops
       }
   }
}

您需要为每个不同的符号定义运算符。

完成此操作后,您已将字符串解析为仅包含重要数据并编译了它们是哪些操作的列表。

现在您需要弄清楚如何应用正确的优先规则等处理该操作列表 :) 最简单的方法可能是每次执行每个有效的计算时重复遍历列表。

1+2*(3+4)-(4+2)

第一关:

1+2*12-6

第二遍:

1+24-6

结果:

19

【讨论】:

    【解决方案4】:

    我的第一次尝试是使用"\b",但这并没有拆分-(。经过一番搜索,我想出了这个:

    (?<=[\(\)\+\-*\/\^A-Za-z])|(?=[\(\)\+\-*\/\^A-Za-z])
    

    因此,您必须将其转义并像这样使用它:

    String input = ...;
    String temp[] = input.split("(?<=[\\(\\)\\+\\-*\\/\\^A-Za-z])|(?=[\\(\\)\\+\\-*\\/\\^A-Za-z])");
    System.out.println(Arrays.toString(temp));
    

    输入:

    7+4-(18/3)/2a^222+1ab
    

    输出:

    [7, +, 4, -, (, 18, /, 3, ), /, 2, a, ^, 222, +, 1, a, b]
    

    在此处查看实际操作:
    http://rubular.com/r/uHAObPwaln
    http://ideone.com/GLFmo4

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 1970-01-01
      相关资源
      最近更新 更多